Is anybody using monadic bind-style programming with Expected<T>

c++, c++11, monads

Solution

Passing normal functions to function templates (say, your `.then`) in C++, as opposed to Haskell, is extremely frustrating. You have to provide an explicit type signature for them if they're overloaded or templates. This is ugly and doesn't lend itself to monadic computation chains.

Also, our current lambdas are monomorphic, you have to explicitly type out the parameter types, which makes this whole situation even worse.

There have been many (library) tries to make functional programming in C++ easier, but it always comes back down to those two points.

Last but not least, functional-style programming in C++ isn't the norm and there are many people to whom that concept is completely alien, while a "return code"-like concept is easy to understand.

(Note that your `.then` function template's `V` parameter has to be specified explicitly, but that is relatively easy fixable.)

Problem

(First of all "bind" in the question has nothing to do with `std::bind`) I have watched the Expected<T> talk and I thought the presentation on the history of this technique was missing the core idea behind this thing in Haskell. The core idea in Haskell is that you "never" acess the value of an `Expected<T>`. What you do instead is pass a lambda to the `Expected<T>` that will either be applied or not depending on the state of the `Expected<T>`. I would have expected this "bind" combinator to be the main method that `Expected<T>` would be used, so I have to ask if this programming style has been rejected for some reason. I'll call that combinator `then` in the following: ``` template <class T> class Expected<T> { .... template <class V, class F> Expected<V> then(F fun_) { if (!valid()) { return Expected<V>::fromException(this(??)); // something like that } return fun_(get()); } } ``` The point of this combinator is to chain a list of functions where you don't need to check for errors, and where the first function that fails will short-circuit the evaluation. ``` auto res = Expected<Foo>::fromCode([]() { return callFun1(...); }) .then([](Baz& val) { return callFun2(..,val,..); }) .then([](Bar& val) { return callFun3(val,...); }); ``` Or this syntax which is starting to resemble the `>>=` operator that is used in Haskell. ``` auto res = []() { return callFun1(...); } >> [](Baz& val) { return callFun2(..,val,..); } >> [](Bar& val) { return callFun3(val,...); }; ``` `callFun1` returns a `Expected<Baz>`, `callFun2` returns a `Expected<Bar>`, and `callFun3` returns a `Expected<Foo>`. As you can see, this code doesn't check for errors. Errors will stop execution, but they still have all the advantages of `Expected<T>`. This is the standard way to use the `Either` monad in Haskell. As I said, surely someone must have looked at this. Edit: I wrote wrong return types for callFun{1..3}. They return `Expected<T>`, not `T` for various values of `T`. This is sort of the whole point of the `then` or `>>` combinator.

Original source