Created
March 13, 2011 04:57
-
-
Save pskupinski/867878 to your computer and use it in GitHub Desktop.
My maybe monad implementation in C++0x.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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