Skip to content

Instantly share code, notes, and snippets.

@kcris
Created November 14, 2012 10:07
Show Gist options
  • Save kcris/4071324 to your computer and use it in GitHub Desktop.
Save kcris/4071324 to your computer and use it in GitHub Desktop.
monad in c++ 03
//
//http://c2.com/cgi/wiki?CeePlusPlusMonadsExample
//
//see also: http://c2.com/cgi/wiki?OnMonads
//
#include <iostream>
template<typename A_>
struct monad
{
template<typename B_>
monad<B_>& operator >>=(monad<B_>& (*f)(A_))
{
return *new monad_bind<A_,B_>(*this,f);
}
static monad<A_>& return_value(A_ a)
{
return *new monad_return<A_>(a);
}
virtual A_ execute() = 0; // this should be protected
private:
template<typename A_,typename B_>
struct monad_bind : public monad<B_>
{
monad_bind(monad<A_>& ma,monad<B_>& (*f)(A_))
: _ma(ma)
, _f(f)
{
}
monad<A_>& _ma;
monad<B_>& (*_f)(A_);
virtual B_ execute()
{
A_ a=_ma.execute();
monad<B_>& mb=_f(a);
return mb.execute();
}
};
template<typename A_>
struct monad_return : public monad<A_>
{
monad_return(A_ a) : _a(a) {}
A_ _a;
virtual A_ execute()
{
return _a;
}
};
};
struct unit
{
};
monad<unit>& write_character(char c)
{
std::cout << c;
return monad<unit>::return_value(unit());
}
monad<char>& read_character(unit)
{
char c;
std::cin >> c;
return monad<char>::return_value(c);
}
monad<char>& is_it_capitalized(char c)
{
return
isupper(c)?
monad<char>::return_value('y')
:
monad<char>::return_value('n');
}
monad<unit>& program(monad<unit>& start)
{
return (((start >>= read_character) >>= is_it_capitalized) >>= write_character);
}
void main(void)
{
monad<unit>& result=program(monad<unit>::return_value(unit()));
unit end=result.execute();
}
//program = read_character >>= is_it_capitalized >>= write_character
//where is_it_capitalized c = if isupper c
//then return 'y'
//else return 'n'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment