<div dir="ltr">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:<div><br></div><div><span class="" style="font-size:13px;margin:0px;padding:0px;color:rgb(0,0,0);font-family:monospace;line-height:16.1200008392334px">class</span><span style="font-size:13px;color:rgb(0,0,0);font-family:monospace;line-height:16.1200008392334px;background-color:rgb(240,240,240)"> </span><a name="t:Error" class="" style="font-size:13px;margin:0px;padding:0px;font-weight:bold;color:rgb(0,0,0);font-family:monospace;line-height:16.1200008392334px">Error</a><span style="font-size:13px;color:rgb(0,0,0);font-family:monospace;line-height:16.1200008392334px;background-color:rgb(240,240,240)"> a </span><span class="" style="font-size:13px;margin:0px;padding:0px;color:rgb(0,0,0);font-family:monospace;line-height:16.1200008392334px">where</span><br></div><div><span class="" style="font-size:13px;margin:0px;padding:0px;color:rgb(0,0,0);font-family:monospace;line-height:16.1200008392334px"> strMsg :: String -> a</span></div><div><span class="" style="font-size:13px;margin:0px;padding:0px;color:rgb(0,0,0);font-family:monospace;line-height:16.1200008392334px"><br></span></div><div><span class="" style="font-size:13px;margin:0px;padding:0px;color:rgb(0,0,0);font-family:monospace;line-height:16.1200008392334px">instance Error e => MonadFail (Either e) where</span></div><div><span class="" style="font-size:13px;margin:0px;padding:0px;color:rgb(0,0,0);font-family:monospace;line-height:16.1200008392334px"> fail = Left . strMsg</span></div><div><br></div><div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>-Edward</div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 10, 2015 at 5:44 PM, David Feuer <span dir="ltr"><<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">My main concern, I suppose, is that I don't see a way (without<br>
extensions) to deal with even the most basic interesting failure<br>
monad: Either e. It therefore seems really only to be suitable for<br>
pattern match failure and user-generated IOErrors, which don't really<br>
strike me as terribly natural bedfellows.<br>
<div class="HOEnZb"><div class="h5"><br>
On Wed, Jun 10, 2015 at 10:55 AM, Edward Kmett <<a href="mailto:ekmett@gmail.com">ekmett@gmail.com</a>> wrote:<br>
> This would require you to add MPTCs to the language standard, which means<br>
> standardizing how they work.<br>
><br>
> Any solution involving SomeException or any of its variants is going to drag<br>
> in GADTs, Typeable, higher rank types.<br>
><br>
> ... and it would drag them inexorably into the Prelude, not just base.<br>
><br>
> Compared to a simple<br>
><br>
> class Monad m => MonadFail m where<br>
> fail :: String -> m a<br>
><br>
> that is a very hard sell!<br>
><br>
> On the other hand, I do think what we could do is add more information about<br>
> pattern match failures by adding another member to the class<br>
><br>
> class Monad m => MonadFail m where<br>
> patternMatchFailure :: Location -> String -> whatever else you like -> m a<br>
> patternMatchFailure l s ... = fail (code to generate the string we<br>
> generate in the compiler using just the parts we're passed)<br>
><br>
> fail :: String -> m a<br>
><br>
> Then the existing 'fail' desugaring could be done in terms of this<br>
> additional member and its default implementation.<br>
><br>
> This remains entirely in the "small" subset of Haskell that is well behaved.<br>
> It doesn't change if we go and radically redefine the way the exception<br>
> hierarchy works, and it doesn't require a ton of standardization effort.<br>
><br>
> Now if we want to make the fail instance for IO or other MonadThrow<br>
> instances package up the patternMatchFailure and throw it in an exception we<br>
> have the freedom, but we're avoid locking ourselves in to actually trying to<br>
> figure out how to standardize all of the particulars of the exception<br>
> machinery into the language standard.<br>
><br>
> -Edward<br>
><br>
> On Wed, Jun 10, 2015 at 4:19 PM, David Feuer <<a href="mailto:david.feuer@gmail.com">david.feuer@gmail.com</a>> wrote:<br>
>><br>
>> Here's a crazy question: would a version of MonadError without the<br>
>> fundep do the trick?<br>
>><br>
>> class Monad m => MonadFail e m where<br>
>> fail :: e -> m a<br>
>><br>
>> instance MonadFail a [] where<br>
>> fail = const []<br>
>><br>
>> instance (a ~ e) => MonadFail e (Either a) where<br>
>> fail = Left<br>
>><br>
>> instance MonadFail SomeException IO where<br>
>> fail = throwIO<br>
>> instance MonadFail IOException IO where<br>
>> fail = throwIO<br>
>> ...<br>
>> instance MonadFail String IO where<br>
>> fail = throwIO . userError<br>
>><br>
>> On Wed, Jun 10, 2015 at 8:32 AM, Mario Blažević <<a href="mailto:blamario@ciktel.net">blamario@ciktel.net</a>><br>
>> wrote:<br>
>> > +1 from me.<br>
>> ><br>
>> > A minor nitpick: the proposal should clarify which of the existing<br>
>> > instances of Monad from base get a MonadFail instance. My understanding<br>
>> > is<br>
>> > that none of them would define fail = error, but that has not been made<br>
>> > explicit.<br>
>> ><br>
>> ><br>
>> > _______________________________________________<br>
>> > Libraries mailing list<br>
>> > <a href="mailto:Libraries@haskell.org">Libraries@haskell.org</a><br>
>> > <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
>> _______________________________________________<br>
>> Libraries mailing list<br>
>> <a href="mailto:Libraries@haskell.org">Libraries@haskell.org</a><br>
>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
><br>
><br>
</div></div></blockquote></div><br></div>