:warning: alga/monoid.hpp

Depends on

Code

#pragma once
#include"maybe.hpp"

template<typename T,typename F>
struct monoid{
    using M=monoid<T,F>;
    maybe<T> val;
    F op;
    monoid(F op):val(maybe<T>()),op(op){}
    monoid(T val,F op):val(maybe<T>(val)),op(op){}
    maybe<T> get(){return val;}
    void set(T x){return val=maybe<T>(x);}
    M operator+(const M& rhs){
        if(val.is_none())return rhs;
        if(rhs.val.is_none())return *this;
        return monoid(op(get().unwrap(),rhs.get().unwrap()),op);
    }
};
#line 2 "alga/maybe.hpp"
#include<cassert>

/**
 * @brief Maybe
 * @see https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%8A%E3%83%89_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)#Maybe%E3%83%A2%E3%83%8A%E3%83%89
 */

template<typename T>
struct maybe{
    bool _is_none;
    T val;
    maybe():_is_none(true){}
    maybe(T val):_is_none(false),val(val){}
    T unwrap()const{
        assert(!_is_none);
        return val;
    }
    T unwrap_or(T e)const{
        return _is_none?e:val;
    }
    bool is_none()const{return _is_none;}
    bool is_some()const{return !_is_none;}
};

template<typename T,typename F>
auto expand(F op){
    return [&op](const maybe<T>& s,const maybe<T>& t){
        if(s.is_none())return t;
        if(t.is_none())return s;
        return maybe<T>(op(s.unwrap(),t.unwrap()));
    };
}
#line 3 "alga/monoid.hpp"

template<typename T,typename F>
struct monoid{
    using M=monoid<T,F>;
    maybe<T> val;
    F op;
    monoid(F op):val(maybe<T>()),op(op){}
    monoid(T val,F op):val(maybe<T>(val)),op(op){}
    maybe<T> get(){return val;}
    void set(T x){return val=maybe<T>(x);}
    M operator+(const M& rhs){
        if(val.is_none())return rhs;
        if(rhs.val.is_none())return *this;
        return monoid(op(get().unwrap(),rhs.get().unwrap()),op);
    }
};
Back to top page