Created
December 15, 2011 04:17
-
-
Save jeremyroman/1479822 to your computer and use it in GitHub Desktop.
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
#include <iostream> | |
#include <string> | |
#include <vector> | |
template <template <typename> class M> | |
class Monad { | |
public: | |
template <typename A, typename B, typename Function> | |
static M<B> monad_bind(M<A> in, Function function); | |
template <typename T> | |
static M<T> monad_return(T data); | |
template <typename T> | |
static M<T> monad_fail(std::string message); | |
}; | |
template <typename T> | |
class lvector : public std::vector<T> { | |
}; | |
template <> | |
class Monad<lvector> { | |
public: | |
template <typename A, typename B, typename Function> | |
static lvector<B> monad_bind(lvector<A> in, Function function) { | |
typename lvector<A>::iterator it_a; | |
typename lvector<A>::iterator it_b; | |
lvector<B> result; | |
for (it_a = in.begin(); it_a != in.end(); ++it_a) { | |
lvector<B> partial_result = function(*it_a); | |
for (it_b = partial_result.begin(); it_b != partial_result.end(); ++it_b) { | |
result.push_back(*it_b); | |
} | |
} | |
return result; | |
} | |
template <typename T> | |
static lvector<T> monad_return(T data) { | |
lvector<T> result; | |
result.push_back(data); | |
return result; | |
} | |
template <typename T> | |
static lvector<T> monad_fail(std::string message) { | |
return lvector<T>(); | |
} | |
}; | |
template <template <typename> class M, typename A, typename B, typename Function> | |
M<B> monad_bind(M<A> in, Function function) { | |
return Monad<M>::template monad_bind<A, B, Function>(in, function); | |
} | |
template <template <typename> class M, typename T> | |
M<T> monad_return(T data) { | |
return Monad<M>::template monad_return<T>(data); | |
} | |
template <template <typename> class M, typename T> | |
M<T> monad_fail(std::string message) { | |
return Monad<M>::template monad_fail<T>(message); | |
} | |
template <typename T> | |
lvector<T> twice(T x) { | |
lvector<T> result; | |
result.push_back(x); | |
result.push_back(x); | |
return result; | |
} | |
int main() { | |
lvector<int> alpha; | |
alpha.push_back(1); | |
alpha.push_back(2); | |
alpha.push_back(3); | |
lvector<int> beta = monad_bind<lvector, int, int, lvector<int>(*)(int)>(alpha, twice<int>); | |
for (lvector<int>::iterator it = beta.begin(); it != beta.end(); ++it) { | |
std::cout << *it << std::endl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment