#include #include #include #include template class Monad { public: Monad(std::tuple t) : params(t){} template auto operator>=(F func) { auto t = std::tuple_cat(params, std::make_tuple(func)); return make_monad(t); } auto run() { return call_func(std::index_sequence_for{}); } private: std::tuple params; template auto call_func(std::index_sequence) { return run_impl(std::get(params)...); } template X run_impl(X x) { std::cout << x << std::endl; return x; } template auto run_impl(X x, F f, Args... args) { std::cout << x << " >= "; return run_impl(f(x), args...); } }; template Monad make_monad(std::tuple t) { return Monad(t); } struct F1 { double operator()(int a) { return a+0.1; } }; struct Mult2 { std::size_t operator()(double d) { return d*2; } }; int main() { Monad m(5); auto i = m >= F1() >= Mult2() >= [](std::size_t x){return x+20;}; std::cout << i.run() << std::endl; }