[Haskell-cafe] Monad m => m (Maybe a) -> m (Maybe a) -> m (Maybe a)

Andras Slemmer 0slemi0 at gmail.com
Thu Nov 13 19:23:12 UTC 2014


> Evan's solution short-circuits: it does not execute the second action if
the first succeeds. But your one runs both actions unconditionally.

Thanks for pointing that out! This is what happens when you only look at
the type of a function and *assume* its implementation:)

Actually this is a great way to shed light on the difference between
monadic and applicative: In the original function the context chaining
itself depends on a computed value (short circuiting), meaning it
"properly" relies on (>>=). liftM2 (<|>) - or rather liftA2 (<|>) - does
not, it doesn't unbox anything, so it cannot possibly be correct.

On 13 November 2014 01:23, Chris Wong <lambda.fairy at gmail.com> wrote:

> On Thu, Nov 13, 2014 at 11:07 AM, Andras Slemmer <0slemi0 at gmail.com>
> wrote:
> > Well, "try" is really doing two things: chaining Maybes, and then adding
> a
> > monadic context:
> > try :: Monad m => m (Maybe a) -> m (Maybe a) -> m (Maybe a)
> > try = liftM2 (<|>)
> > (You could weaken the assumption by using (Applicative m) instead)
>
> That's different to Evan's original function.
>
> Evan's solution short-circuits: it does not execute the second action
> if the first succeeds. But your one runs both actions unconditionally.
>
> For example, the expression
>
>     try (return $ Just ()) (putStrLn "second action executed" >> return
> Nothing)
>
> outputs "second action executed" with your solution, but not with Evan's.
>
> The lesson is, applicative and monadic composition don't always yield
> the same results.
>
> Chris
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20141113/63f3aa0c/attachment.html>


More information about the Haskell-Cafe mailing list