Skip to content

Instantly share code, notes, and snippets.

@rsbowman
Created September 25, 2015 16:24
Show Gist options
  • Select an option

  • Save rsbowman/9bbb3a249f4e6b715b04 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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