Skip to content

Instantly share code, notes, and snippets.

@rsbowman
Created September 25, 2015 16:24
Show Gist options
  • Save rsbowman/9bbb3a249f4e6b715b04 to your computer and use it in GitHub Desktop.
Save rsbowman/9bbb3a249f4e6b715b04 to your computer and use it in GitHub Desktop.
#include <iostream>
using namespace std;
template <typename T>
class Maybe {
T v;
bool _ok;
public:
Maybe(T val) : v(val), _ok(true) {}
Maybe() : _ok(false) {}
bool ok() const { return _ok; }
T val() const { return v; }
friend ostream& operator<<(ostream &os, const Maybe& m) {
if (m.ok()) {
os << "Maybe(" << m.v << ")";
} else {
os << "Nothing";
}
return os;
}
};
template <typename T>
Maybe<T> unit(const T& v) {
return Maybe<T>(v);
}
template <typename T, typename F>
auto bind(const Maybe<T>& m, F&& f) -> decltype(f(m.val())) {
typedef decltype(f(m.val()).val()) B;
if (m.ok()) {
return f(m.val());
} else {
return Maybe<B>();
}
}
template <typename T>
Maybe<T> add(const Maybe<T>& a, const Maybe<T>& b) {
auto sum = bind(a, [&](T x) {
return bind(b, [&](T y) {
return unit(x + y);
});
});
return sum;
}
int main(void) {
auto m1 = Maybe<int>(3);
auto m2 = Maybe<int>(5);
auto n = Maybe<int>();
cout << m1 << " + " << m2 << " = " << add(m1, m2) << endl;
cout << m1 << " + " << n << " = " << add(m1, n) << endl;
cout << n << " + " << m2 << " = " << add(n, m2) << endl;
return 0;
}
@jjoconnor
Copy link

What in the name of all that is holy...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment