MonadFail proposal (MFP): Moving fail out of Monad

Edward Kmett ekmett at
Wed Jun 10 14:55:30 UTC 2015

This would require you to add MPTCs to the language standard, which means
standardizing how they work.

Any solution involving SomeException or any of its variants is going to
drag in GADTs, Typeable, higher rank types.

... and it would drag them inexorably into the Prelude, not just base.

Compared to a simple

class Monad m => MonadFail m where
  fail :: String -> m a

that is a very hard sell!

On the other hand, I do think what we could do is add more information
about pattern match failures by adding another member to the class

class Monad m => MonadFail m where
  patternMatchFailure :: Location -> String -> whatever else you like -> m a
  patternMatchFailure l s ... = fail (code to generate the string we
generate in the compiler using just the parts we're passed)

  fail :: String -> m a

Then the existing 'fail' desugaring could be done in terms of this
additional member and its default implementation.

This remains entirely in the "small" subset of Haskell that is well
behaved. It doesn't change if we go and radically redefine the way the
exception hierarchy works, and it doesn't require a ton of standardization

Now if we want to make the fail instance for IO or other MonadThrow
instances package up the patternMatchFailure and throw it in an exception
we have the freedom, but we're avoid locking ourselves in to actually
trying to figure out how to standardize all of the particulars of the
exception machinery into the language standard.


On Wed, Jun 10, 2015 at 4:19 PM, David Feuer <david.feuer at> wrote:

> Here's a crazy question: would a version of MonadError without the
> fundep do the trick?
> class Monad m => MonadFail e m where
>   fail :: e -> m a
> instance MonadFail a [] where
>   fail = const []
> instance (a ~ e) => MonadFail e (Either a) where
>   fail = Left
> instance MonadFail SomeException IO where
>   fail = throwIO
> instance MonadFail IOException IO where
>   fail = throwIO
> ...
> instance MonadFail String IO where
>   fail = throwIO . userError
> On Wed, Jun 10, 2015 at 8:32 AM, Mario Blažević <blamario at>
> wrote:
> > +1 from me.
> >
> >     A minor nitpick: the proposal should clarify which of the existing
> > instances of Monad from base get a MonadFail instance. My understanding
> is
> > that none of them would define fail = error, but that has not been made
> > explicit.
> >
> >
> > _______________________________________________
> > Libraries mailing list
> > Libraries at
> >
> _______________________________________________
> Libraries mailing list
> Libraries at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Libraries mailing list