Removing MonadFail from Monad

John Lato jwlato at
Tue Dec 17 00:47:42 UTC 2013

On Mon, Dec 16, 2013 at 2:54 PM, Tom Ellis <
tom-lists-haskell-cafe-2013 at> wrote:

> On Mon, Dec 16, 2013 at 11:26:39PM +0100, David Luposchainsky wrote:
> > I feel like there are a couple of elephants in the room that are sort of
> > important but nobody really addresses them directly. One of them was
> > what became the AMP, and `fail` is another one.
> Is it written up somewhere why pattern match failure in 'do' is a 'fail'
> but
> pattern match failure elsewhere is just pattern match failure?
> Malcolm Wallace mentioned that it convenient when writing parsers, and his
> example is indeed neat, but is has someone done a more substantial
> investigation the benefits of this special case?

AFAIK, it was done this way for list comprehensions.  Currently, you can
write e.g.

> rights = [x | Right x <- listOfEithers]

and it works properly. The list comprehension is desugared to

> do { Right x <- listOfEithers; return x }

which becomes

> do { listOfEithers >>= \l -> case l of { Right x -> return x; _ -> fail
"location" }}

since the Monad instance for lists defines fail = const [], everything
works out.  The nearly-equivalent code,

> listOfEithers >>= \(Right x) -> return x

indeed results in a PatternMatchFail exception.  The difference is that in
the former case, the fail method is called in lieu of the remainder of the
do-expression, whereas the lambda pattern match failure calls throw.
Throwing an exception wouldn't work for this because they can't be caught
outside IO.

(I think this applies to generalized monad comprehensions as well, although
I've never tried that)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Libraries mailing list