<div dir="auto">Looks like `MonadError String` to me.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 20 Nov 2020, 1:08 pm Dannyu NDos, <<a href="mailto:ndospark320@gmail.com">ndospark320@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Firstly, I propose a new class. This class is like MonadFail, but with<br>
"error bind" operator:<br>
<br>
    class Monad m => FailMsg m where<br>
    failMsg :: String -> m a<br>
    (>?=) :: m a -> (String -> m a) -> m a<br>
<br>
Laws are:<br>
<br>
 * For every (x :: m a), if (x ≡ fail msg) for some (msg :: String),<br>
msg shall be unique.<br>
 * For (x ≡ fail msg), (x >?= f ≡ f msg). If such msg doesn't exist,<br>
(x >?= _ ≡ x).<br>
<br>
Basic instances are:<br>
<br>
    instance e ~ String => FailMsg (Either e) where<br>
        failMsg = Left<br>
        Left msg >?= f = f msg<br>
        x >?= _ = x<br>
<br>
    instance FailMsg IO where<br>
        failMsg = throwIO . userError<br>
        action >?= f = catch action (f . ioeGetErrorString)<br>
<br>
Now let's focus on ReadP. Let P carry a failure message:<br>
<br>
    data P a<br>
        = Get (Char -> P a)<br>
        | Look (String -> P a)<br>
        | Fail String<br>
        | Result a (P a)<br>
        | Final (NonEmpty (a,String))<br>
<br>
Then we have:<br>
<br>
    instance FailMsg P where<br>
        fail = Fail<br>
        Fail msg >?= f = f msg<br>
        p >?= _ = p<br>
<br>
    instance FailMsg ReadP where<br>
        fail msg = R (\_ -> fail msg)<br>
        R m >?= f = R (\k -> case m k of<br>
            Fail msg -> let<br>
                R n = f msg<br>
            in n k<br>
            p -> p<br>
            )<br>
<br>
This is incredibly useful. This can be used when there are multiple<br>
types of parse error.<br>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank" rel="noreferrer">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>