On 13-06-24 11:53 AM, Pierre Talbot wrote:
This misses what is, IMO, the most important use case of Haskell's Either monad: automatic error propagation. This would be more useful if there were a way to call a function such that if any of the function's arguments were an Either-in-error, the function would immediately return the error.
I implemented something like this. Check out substitution_failure and try_call starting here:
https://github.com/ericniebler/proto-0x/blob/master/boost/proto/v5/utility.h...
In the Expected proposal, there are some methods related to this idea.
Glad it's been considered!
Actually, the "then" method can be applied on an expected and immediately returns the expected if it contains an error. Furthermore, you can chain function calls until one of these fail.
Here one of the use-case shown in the proposal:
expected<int> create_and_connect() { return socket() // call the function socket that creates an expected. .then(connect) // Pass the expected handle to connect if it contains a value, otherwise just returns it. .on_error(error_resolver); // Use the error_resolver if the last expected contains an error, otherwise just returns it. }
There is maybe two advantages to this then function:
* Chaining multiple calls. * A specific error resolver in case of failure.
But it doesn't offer multiple argument check, and that's why we also proposed if_all:
if_all(f(), g()).then(h).on_error(error_resolver);
I think this one is much more related to your function.
I'm not sure that hits the mark. What if you want to call h with the results of calling f and g, but only if f() and g() return non-errors? That is, what would this look like in your proposed system: // if h or g fails, h return immediately. h(f(), "hello world", g(), 42); I'm partial to this: // if h or g fails, h return immediately. try_call(h)(f(), "hello world", g(), 42);
I honestly think that if Either goes into Boost, we shouldn't consider it as a value or error structure at all. Expected (will) do the job.
Seems a bit excessive to me to have both. If we get Expected, then Either is unnecessary -- it's just one template alias away from variant. I don't consider the syntactic niceties of "left" and "right" to be compelling, and if folks want it, we can provide left and right free functions for 2-arg variants. But IMO automatic error propagation is the *only* thing that can make this proposal compelling. And while I'm thinking of it, I see lots of potential with try_call and C++14's generic lambdas. Wish I had a compiler that implements them. In the above, if h is not something that can be passed as a parameter, you'd want this: try_call([](auto &&...args){return h(forward<decltype-dance>(args)...);})(f(), "hello world", g(), 42); This begs to be wrapped up in a macro. -- Eric Niebler Boost.org