MonadFail proposal (MFP): Moving fail out of Monad

Mario Blažević mblazevic at
Thu Jun 11 15:18:38 UTC 2015

On 15-06-10 03:48 PM, Edward Kmett wrote:
> I mentioned in another thread on this topic that it may be perfectly
> reasonable to extend the class with another method that handles just the
> pattern match failure case with the details necessary to reproduce the
> current errors.
> class Monad m => MonadFail m where
>    fail :: String -> m a
>    patternMatchFailure :: Location -> CallStack -> Whatever Other
> Information You Like -> String -> m a
>    patternMatchFailure l w ... = fail (code to generate the string we
> produce now using the inputs given)
> Then a particular concrete MonadFail instance could choose to throw a
> GHC style extensible exception, it could format the string, it could
> default to mzero, etc.

	I'm +1 on this extension. May I suggest some of Whatever Other
Information You Like? I wonder if the following method would be 
implementable in GHC:

 >    patternMatchFailureOnData :: (Data a, Data b) =>
 >         Location -> CallStack
 >         -> String         --^ the fail message
 >         -> a              --^ the RHS of the failed assignment
 >         -> (a -> Maybe b) --^ the failed LHS pattern
 >         -> (b -> m c)     --^ do continuation
 >         -> m a

	The method would default to plain patternMatchOnFailure, which would 
default to fail. It would be invoked on a pattern-match failure iff the 
type of the RHS has a Data instance in scope. This way an EDSL monad 
could get some actual use out of the fail mechanism and recover from a 

> instance MonadFail IO where
>    patternMatchFailure a b c .. = throwIO $ PatternMatchFailure a b c ..
> But if we don't capture the location information / string / whatever
> _somehow_ then we lose information relative to the status quo, just by
> going down to mzero on a failure. Users use this in their debugging
> today to find where code went wrong that they weren't expecting to go wrong.
> Beyond handling these two "traditional" error cases, I think everything
> else should be left to something that doesn't infect as central a place
> as Prelude.
> Doing a "general" MonadError with fundeps or without fundeps and just
> MPTCs still requires you to extend the language of the standard to
> support language features it doesn't currently incorporate.
> Trying to upgrade 'fail' itself to take an argument that isn't just a
> String breaks all the code that uses -XOverloadedStrings, so if you want
> more information it is going to have to be in a different method than
> fail, but it could live in the same class.
> Finally fail has different semantics than mzero for important monads
> like STM that exist today.
> -Edward

More information about the Libraries mailing list