tuple monad (with maybe for filtering)
#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <experimental/optional>
#include <utility>
auto naked_tuple = [](auto... xs)
{
return [=](auto f)
{
return f(xs...);
};
};
auto push_back = [](auto t , auto... xs)
{
auto closure = [=](auto... ys)
{
return naked_tuple(ys...,xs...);
};
return t(closure);
};
template<typename T , typename HEAD , typename... TAIL>
auto filter_nil(T tuple_result , HEAD&& head , TAIL&&... tail)
{
return filter_nil(push_back(tuple_result,std::forward<HEAD>(head)),std::forward<TAIL>(tail)...);
}
template<typename T , typename... TAIL>
auto filter_nil(T tuple_result , std::experimental::nullopt_t&& head , TAIL&&... tail)
{
return filter_nil(tuple_result,tail...);
}
template<typename T>
auto filter_nil(T tuple_result)
{
return tuple_result;
}
auto strip_tuple = [](auto... xs)
{
return [=](auto f)
{
return f(xs.get()...);
};
};
auto tuple = [](auto... xs)
{
return [=](auto f)
{
return filter_nil(strip_tuple(),std::experimental::make_optional(xs)... )(f);
};
};
auto map = [](auto... xs)
{
return [=](auto f){ return tuple(f(xs)...); };
};
auto write = [](auto x)
{
std::cout << " " << x << " ";
};