Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save thehydroimpulse/3065542 to your computer and use it in GitHub Desktop.
Save thehydroimpulse/3065542 to your computer and use it in GitHub Desktop.
My maybe monad implementation in C++0x.
// This code is in the public domain, feel free to use it in anyway you'd
// like to.
#include <iostream>
#include <functional>
using namespace std;
template<class A>
class Maybe {
protected:
A a;
bool nothing;
// a -> M a
Maybe(A a): a(a), nothing(false) {}
Maybe(): nothing(true) {}
public:
// (M a) -> (a -> M b) -> (M b)
template<class B>
Maybe<B> bind(function<Maybe<B> (A)> f);
bool isNothing();
A getOrElse(A defaultValue);
};
template<class A>
class Nothing : public Maybe<A> {
public:
Nothing(): Maybe<A>() {}
};
template<class A>
class Just : public Maybe<A> {
public:
Just(A a): Maybe<A>(a) {}
};
template<class A> template<class B>
Maybe<B> Maybe<A>::bind(function<Maybe<B> (A)> f) {
if(nothing)
return Nothing<B>();
else
return f(a);
}
template<class A>
bool Maybe<A>::isNothing() {
return nothing;
}
template<class A>
A Maybe<A>::getOrElse(A defaultValue) {
if(nothing)
return defaultValue;
else
return a;
}
int main() {
function<Maybe<int> (int)> maybePrintInt = [](int i) -> Maybe<int> {
cout << "i = " << i << endl;
return Just<int>(i);
};
function<Maybe<int> (int)> maybeAddFive = [](int i) -> Maybe<int> {
return Just<int>(i+5);
};
int input;
Maybe<int>* inputNumber;
cout << "Please give me an int: ";
cin >> input;
if(cin.fail()) {
inputNumber = new Nothing<int>();
} else {
inputNumber = new Just<int>(input);
}
if(inputNumber->bind(maybeAddFive).bind(maybePrintInt).isNothing())
cout << "Invalid number given!" << endl;
delete inputNumber;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment