Skip to content

Instantly share code, notes, and snippets.

@tfc
Last active July 4, 2017 07:39
Show Gist options
  • Save tfc/c25591ef8e25e5609b39ab0080ab1e5f to your computer and use it in GitHub Desktop.
Save tfc/c25591ef8e25e5609b39ab0080ab1e5f to your computer and use it in GitHub Desktop.
Transform a function from `R f(P ... ps)` to `std::optional<R> f(std::optional<P> ... ps)` and use it monadic style. needs C++17.
#include <iostream>
#include <optional>
/// library part
template <typename R, typename ... P>
auto lift_optional(R (*f)(P ... ps))
{
return [f](std::optional<P> ... xs) -> std::optional<R> {
if ((xs && ...)) {
return {f(*(xs)...)};
} else {
return {};
}
};
}
template <typename T>
std::ostream& operator<<(std::ostream &os, const std::optional<T> &mt)
{
if (mt) {
return os << "Just " << *mt;
} else {
return os << "Nothing";
}
}
/// user code
int f(int a, int b)
{
return a + b;
}
int g(int a)
{
return 2 * a;
}
auto mf = lift_optional(f);
auto mg = lift_optional(g);
int main()
{
std::cout << mg(mf({1}, {})) << '\n';
std::cout << mg(mf({1}, {2})) << '\n';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment