Hehe, but that's actual code.
> we may go back to our C++14 code base and implement the ideas there. I’m not going to show you how this can be done here, as it requires some more boilerplate code to make the compiler happy – as usual.
People are going to want to see the code, otherwise, what's the point?
I'm playing around with what is now my second iteration of Monadic Bind and Kleisli Composition for boost::optional, which looks something like this right now:
// tag dispatch work around for void returning functions (that make no sense in a purely functional world)
namespace detail {
template <typename A, typename Fn>
auto monadicBindImpl(const boost::optional<A>& a, Fn f, std::false_type) -> decltype(f(*a)) {
if (a) return f(*a); else return {};
}
template <typename A, typename Fn>
auto monadicBindImpl(const boost::optional<A>& a, Fn f, std::true_type) -> void {
if (a) f(*a);
}
}
template <typename A>
auto pure(A&& a) { return boost::optional<A>(std::forward<A>(a)); }
template <typename A, typename Fn>
auto operator>>=(const boost::optional<A>& a, Fn f) -> decltype(f(*a)) {
return detail::monadicBindImpl(a, f, typename std::is_same<decltype(f(*a)), void>{});
}
Kleisli Composition can then be build with C++14's generic polymorphic lambdas exactly like the Haskell implementation does it: https://hackage.haskell.org/package/base-4.6.0.1/docs/src/Co...There are other articles on the web for Monads in C++, that probably do a better job at an actual implementation. Please see this as my personal playground code :)