#include <iostream>
#include <functional>
#include <vector>
#include <iterator>
using namespace std;
template <typename T>
struct unwrap;
template <template <class...> class F, typename X, typename... XS>
struct unwrap<F<X, XS...>> {
typedef X type;
};
template <template <class...> class>
struct monad;
template <template <class...> class M, typename A, typename F>
auto operator >>=(M<A> const & x, F f) -> M<typename unwrap<decltype(declval<F>()(declval<A>()))>::type> {
return monad<M>::bind(x, f);
};
template <template <class...> class M, typename T>
auto return_(T x) -> M<T> {
return monad<M>::return_(x);
}
template <>
struct monad<vector> {
template <typename A, typename F>
static auto bind(vector<A> const & x, F f) -> vector<typename unwrap<decltype(declval<F>()(declval<A>()))>::type> {
typedef typename unwrap<decltype(declval<F>()(declval<A>()))>::type B;
vector<B> ret;
for (typename vector<A>::const_iterator it = x.begin(), iend = x.end(); it != iend; ++it) {
vector<B> r = f(*it);
copy(r.begin(), r.end(), back_inserter(ret));
}
return ret;
}
template <typename T>
static auto return_(T x) -> vector<T> {
return vector<T>(1, x);
}
};
int main() {
vector<int> v = {1, 2, 3}, w = {1, 2, 3};
vector<int> r = v >>= [&](int x) { return w >>= [&](int y) { return return_<vector, int>(x+y); }; };
copy(r.begin(), r.end(), ostream_iterator<int>(cout, " "));
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGl0ZXJhdG9yPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCB1bndyYXA7CnRlbXBsYXRlIDx0ZW1wbGF0ZSA8Y2xhc3MuLi4+IGNsYXNzIEYsIHR5cGVuYW1lIFgsIHR5cGVuYW1lLi4uIFhTPgpzdHJ1Y3QgdW53cmFwPEY8WCwgWFMuLi4+PiB7CiAgICB0eXBlZGVmIFggdHlwZTsKfTsKCnRlbXBsYXRlIDx0ZW1wbGF0ZSA8Y2xhc3MuLi4+IGNsYXNzPgpzdHJ1Y3QgbW9uYWQ7CnRlbXBsYXRlIDx0ZW1wbGF0ZSA8Y2xhc3MuLi4+IGNsYXNzIE0sIHR5cGVuYW1lIEEsIHR5cGVuYW1lIEY+CmF1dG8gb3BlcmF0b3IgPj49KE08QT4gY29uc3QgJiB4LCBGIGYpIC0+IE08dHlwZW5hbWUgdW53cmFwPGRlY2x0eXBlKGRlY2x2YWw8Rj4oKShkZWNsdmFsPEE+KCkpKT46OnR5cGU+IHsKCXJldHVybiBtb25hZDxNPjo6YmluZCh4LCBmKTsKfTsKdGVtcGxhdGUgPHRlbXBsYXRlIDxjbGFzcy4uLj4gY2xhc3MgTSwgdHlwZW5hbWUgVD4KYXV0byByZXR1cm5fKFQgeCkgLT4gTTxUPiB7CglyZXR1cm4gbW9uYWQ8TT46OnJldHVybl8oeCk7Cn0KCnRlbXBsYXRlIDw+CnN0cnVjdCBtb25hZDx2ZWN0b3I+IHsKCXRlbXBsYXRlIDx0eXBlbmFtZSBBLCB0eXBlbmFtZSBGPgoJc3RhdGljIGF1dG8gYmluZCh2ZWN0b3I8QT4gY29uc3QgJiB4LCBGIGYpIC0+IHZlY3Rvcjx0eXBlbmFtZSB1bndyYXA8ZGVjbHR5cGUoZGVjbHZhbDxGPigpKGRlY2x2YWw8QT4oKSkpPjo6dHlwZT4gewoJCXR5cGVkZWYgdHlwZW5hbWUgdW53cmFwPGRlY2x0eXBlKGRlY2x2YWw8Rj4oKShkZWNsdmFsPEE+KCkpKT46OnR5cGUgQjsKCQl2ZWN0b3I8Qj4gcmV0OwoJCWZvciAodHlwZW5hbWUgdmVjdG9yPEE+Ojpjb25zdF9pdGVyYXRvciBpdCA9IHguYmVnaW4oKSwgaWVuZCA9IHguZW5kKCk7IGl0ICE9IGllbmQ7ICsraXQpIHsKCQkJdmVjdG9yPEI+IHIgPSBmKCppdCk7CgkJCWNvcHkoci5iZWdpbigpLCByLmVuZCgpLCBiYWNrX2luc2VydGVyKHJldCkpOwoJCX0KCQlyZXR1cm4gcmV0OwoJfQoJdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CglzdGF0aWMgYXV0byByZXR1cm5fKFQgeCkgLT4gdmVjdG9yPFQ+IHsKCQlyZXR1cm4gdmVjdG9yPFQ+KDEsIHgpOwoJfQp9OwoKaW50IG1haW4oKSB7Cgl2ZWN0b3I8aW50PiB2ID0gezEsIDIsIDN9LCB3ID0gezEsIDIsIDN9OwoJdmVjdG9yPGludD4gciA9IHYgPj49IFsmXShpbnQgeCkgeyByZXR1cm4gdyA+Pj0gWyZdKGludCB5KSB7IHJldHVybiByZXR1cm5fPHZlY3RvciwgaW50Pih4K3kpOyB9OyB9OwoJY29weShyLmJlZ2luKCksIHIuZW5kKCksIG9zdHJlYW1faXRlcmF0b3I8aW50Pihjb3V0LCAiICIpKTsKfQ==