Skip to content

Instantly share code, notes, and snippets.

@nekko1119
Last active December 20, 2016 21:32
Show Gist options
  • Save nekko1119/0e2d4b6215c6aca4070d4f829d3e2220 to your computer and use it in GitHub Desktop.
Save nekko1119/0e2d4b6215c6aca4070d4f829d3e2220 to your computer and use it in GitHub Desktop.
#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();
}
#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