Last active
December 20, 2016 21:32
-
-
Save nekko1119/0e2d4b6215c6aca4070d4f829d3e2220 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
struct unit_t {} unit = {}; | |
template <typename T> | |
auto putStrLn(T const& value) { | |
return [&]() { | |
std::cout << value << std::endl; | |
return unit; | |
}; | |
} | |
auto const getLine = []() { | |
std::string str; | |
std::getline(std::cin, str); | |
return str; | |
}; | |
template <typename IO, typename F> | |
auto bind(IO const& io, F f) { | |
return [&]() { | |
return f(io())(); | |
}; | |
} | |
template <typename IO1, typename IO2> | |
auto concat(IO1 const& io1, IO2 const& io2) { | |
return bind(io1, [&](auto) { | |
return io2; | |
}); | |
} | |
int main() { | |
auto const program = concat( | |
putStrLn("please input..."), | |
bind(getLine, [&](std::string const& input) { return putStrLn(input); }) | |
); | |
program(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <functional> | |
struct unit_t {} unit = {}; | |
template <typename T> | |
struct io_t { | |
std::function<T ()> f; | |
template <typename F> | |
explicit io_t(F&& f) : f{std::forward<F>(f)} {} | |
T operator()() const { | |
return f(); | |
} | |
}; | |
template <typename T> | |
struct remove_io_t { | |
using type = T; | |
}; | |
template <typename T> | |
struct remove_io_t<io_t<T>> { | |
using type = T; | |
}; | |
template <typename T> | |
using remove_io_t_t = typename remove_io_t<T>::type; | |
template <typename T, typename F> | |
io_t<T> io(F&& f) { | |
return io_t<T>{std::forward<F>(f)}; | |
} | |
template <typename T> | |
io_t<unit_t> putStrLn(T const& value) { | |
return io<unit_t>([&]() { | |
std::cout << value << std::endl; | |
return unit; | |
}); | |
} | |
io_t<std::string> const getLine = io<std::string>([]() { | |
std::string str; | |
std::getline(std::cin, str); | |
return str; | |
}); | |
template <typename A, typename F, typename R = remove_io_t_t<std::result_of_t<F (A)>>> | |
io_t<R> bind(io_t<A> const& io_a, F&& f) { | |
return io<R>([&]() { | |
return f(io_a())(); | |
}); | |
} | |
template <typename A, typename B> | |
io_t<B> concat(io_t<A> const& io1, io_t<B> const& io2) { | |
return bind(io1, [&](A) { | |
return io2; | |
}); | |
} | |
int main() { | |
io_t<unit_t> const program = concat( | |
putStrLn("please input..."), | |
bind(getLine, [](std::string const& input) { return putStrLn(input); }) | |
); | |
program(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment