Skip to content

Instantly share code, notes, and snippets.

@dabrahams
Created December 30, 2011 18:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dabrahams/1540941 to your computer and use it in GitHub Desktop.
Save dabrahams/1540941 to your computer and use it in GitHub Desktop.
C++11 non-lazy monad
#include <boost/optional.hpp>
#include <utility>
#include <string>
#include <cassert>
template <class T>
struct maybe
{
maybe() {}
maybe(T x) : value(std::move(x)) {}
explicit operator T() const { return value; }
boost::optional<T> value;
};
template <class T, class F>
auto operator>>(maybe<T> const& x, F f) -> decltype(f(*x.value))
{
return x.value ? f(*x.value) : decltype(f(*x.value))();
}
maybe<int> f(int x) { return x < 0 ? maybe<int>() : x; }
maybe<std::string> xes(unsigned int n) { return std::string(n, 'x'); }
maybe<unsigned> length(std::string const& s) { return s.size(); }
int main()
{
assert(*(f(10) >> xes >> length).value == 10);
assert(!(f(-10) >> xes >> length).value);
assert(!(f(-10) >> xes).value);
assert(!f(-10).value);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment