MonadFail proposal (MFP): Moving fail out of Monad
Mario Blažević
mblazevic at stilo.com
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
failure.
>
> 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