
On Tue, Jun 25, 2013 at 8:27 AM, Larry Evans <cppljevans@suddenlink.net>wrote:
On 06/24/13 22:55, David Sankel wrote:
On Mon, Jun 24, 2013 at 1:19 PM, Eric Niebler <eniebler@boost.org> wrote:
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.
<snip various do-syntax derivatives>
If we really care about adding a do syntax EDSL, why not make it general purpose like Haskell's version so that it can work with any monad and compose better with other things?
either<error, int> result = do( set( _x, getInt ), set( _y, getInt ), doReturn( pure( _x + _y ) ) );
If we're going to do that, lets do it generically and completely.
+1
David, is there source code demonstrating this do syntax?
I haven't made a library. That was off the top of my head.
Could you show how to do Eric's example with this do syntax?
Eric's example was: // if h or g fails, h return immediately. try_call(h)(f(), "hello world", g(), 42); Using do syntax, something like... do( set( _fResult, f ), set( _gResult, g ), doReturn( app( h, _fResult, "hello world", _gResult, 42 ) ) ); Well, actually this improves efficiency, if f has an 'error' then g won't be evaluated. But, the more I think of this, the more I think something like indices would work very well here. _1 would refer to the result of the first statement, _2 the result of the second, etc. I also prefer the 'pure' moniker instead of 'return' for taking a non-wrapped value and putting it into a wrapped one. do( app( f ), app( g ), pure( app( h, _1, "hello world", _2, 42 ) ) ); This works with the following: either<Error, A> f(); either<Error, B> g(); C h( A, std::string, B, int ); But would also work with, optional< A> f(); optional< B> g(); C h( A, std::string, B, int );