Manu343726
11/21/2014 - 2:48 PM

tuple monad (with maybe for filtering)

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 << " ";  
};