#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, " "));
}