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