MonadFail proposal (MFP): Moving fail out of Monad

David Feuer david.feuer at gmail.com
Wed Jun 10 16:07:00 UTC 2015


But why does a string actually make sense in the context of handling
pattern match failures? Sticking to a Haskell 98 solution, I would
think MonadZero would be the way to go for those, rather than
MonadFail. What, after all, can you really do with the string
generated by a pattern match failure? For everything other than
pattern match failures, I would think the user should use MonadError,
a non-fundep MonadError, or just work directly without classes.

On Wed, Jun 10, 2015 at 11:53 AM, Edward Kmett <ekmett at gmail.com> wrote:
> You could handle that case explicitly by giving a class that converted a
> string into e and putting that constraint on the MonadFail instance for
> Either:
>
> class Error a where
>   strMsg :: String -> a
>
> instance Error e => MonadFail (Either e) where
>   fail = Left . strMsg
>
> We used to do this in the mtl, with the Error class, but it then had to
> encumber the entire Monad, so even folks who didn't want it needed to supply
> a garbage instance.
>
> Right now, fail for Either is necessarily _error_ because we can't put it in
> the left side without incurring a constraint on every user of the monad.
>
> At least here the ad hoc construction can be offloaded to the particular
> MonadFail instance, or to whatever monad someone makes up for working with
> their Either-like construction.
>
> -Edward
>
> On Wed, Jun 10, 2015 at 5:44 PM, David Feuer <david.feuer at gmail.com> wrote:
>>
>> My main concern, I suppose, is that I don't see a way (without
>> extensions) to deal with even the most basic interesting failure
>> monad: Either e. It therefore seems really only to be suitable for
>> pattern match failure and user-generated IOErrors, which don't really
>> strike me as terribly natural bedfellows.
>>
>> On Wed, Jun 10, 2015 at 10:55 AM, Edward Kmett <ekmett at gmail.com> wrote:
>> > 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 effort.
>> >
>> > 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.
>> >
>> > -Edward
>> >
>> > On Wed, Jun 10, 2015 at 4:19 PM, David Feuer <david.feuer at gmail.com>
>> > 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 ciktel.net>
>> >> 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 haskell.org
>> >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>> >> _______________________________________________
>> >> Libraries mailing list
>> >> Libraries at haskell.org
>> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>> >
>> >
>
>


More information about the Libraries mailing list