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
namespace hask { | |
struct Unit { }; | |
template<typename S> | |
struct Stateful { | |
template<typename V> | |
struct Value | |
{ | |
std::function<std::pair<S,V>(S)> runState; | |
}; | |
}; | |
template<typename S, typename V> | |
typename Stateful<S>::template Value<V> ret(const V& v) | |
{ | |
decltype(ret<S>(v)) rv; | |
rv.runState = [=](S s) { return std::make_pair(s, v); }; | |
return rv; | |
} | |
template<typename S> | |
typename Stateful<S>::template Value<S> get() | |
{ | |
Stateful<S>::Value<S> rv; | |
rv.runState = [](S s) { return std::make_pair(s,s); }; | |
return rv; | |
} | |
template<typename S> | |
typename Stateful<S>::template Value<Unit> put(const S& s) | |
{ | |
Stateful<S>::Value<Unit> rv; | |
rv.runState = [=](S ) { return std::make_pair(s, Unit()); }; | |
return rv; | |
} | |
template<typename S, typename A, typename R> | |
typename Stateful<S>::template Value<R> bind(typename Stateful<S>::template Value<A> a, | |
std::function<typename Stateful<S>::template Value<R> (typename A)> f) | |
{ | |
Stateful<S>::Value<R> rv; | |
rv.runState = [=](S init) -> std::pair<S,R> | |
{ | |
std::pair<S, A> p = a.runState(init); | |
Stateful<S>::Value<R> act2 = f(p.second); | |
return act2.runState(p.first); | |
}; | |
return rv; | |
} | |
template<typename S, typename A, typename R> | |
typename Stateful<S>::template Value<R> seq(typename Stateful<S>::template Value<A> a, typename Stateful<S>::template Value<R> r) | |
{ | |
return bind<S,A,R>(a, [=](A) { return r; }); | |
} | |
template<typename S, typename V> | |
typename Stateful<S>::template Value<V> lift0(std::function<V()> f) | |
{ | |
Stateful<S>::Value<V> rv; | |
rv.runState = [=](S s) { return std::make_pair(s, f()); }; | |
return rv; | |
} | |
} | |
using namespace hask; | |
Stateful<int>::template Value<int> getit = get<int>(); | |
std::function< decltype(hask::put<int>(0)) (int) > doit = [](int x) { return hask::put(x + 1); }; | |
Stateful<int>::Value<Unit> incrS = hask::bind<int, int, Unit>(getit, doit); | |
std::cout << incrS.runState(7).first << std::endl; |
No comments:
Post a Comment