Re: Proposal: add laws to MonadError
David Feuer <[email protected]> Fri, 9 Sep 2022 20:56:43 -0400
| Newsgroups | gmane.comp.lang.haskell.libraries |
|---|---|
| Message-ID | <CAMgWh9vvJ+Eo2VLXRQ4V7Jn1yoPpR+1N8M168n7imb5i2LqOtQ@mail.gmail.com> |
--===============8794242309512341912== Content-Type: multipart/alternative; boundary="0000000000009c165605e8482391" --0000000000009c165605e8482391 Content-Type: text/plain; charset="UTF-8" Sorry, I mangled that. I meant catchError (m >>= f) h = catchError (Right <$> m) (pure . Left) >>= either h ((`catchError` h) . f) On Fri, Sep 9, 2022, 8:49 PM David Feuer <[email protected]> wrote: > I agree. These are still insufficient for much reasoning, however. I would > intuitively expect that > > catchError (m >>= f) h = catchError (Right <$> m) (pure . Left) >>= > either throwError ((`catchError` h) . f) > > But I have no idea whether all "reasonable" instances obey that. > > Is there anything useful to say about the case when the argument to > mapError is sufficiently nice (a monad morphism with some extra property, > for instance? > > On Fri, Sep 9, 2022, 5:43 PM Alexandre Esteves < > [email protected]> wrote: > >> I ran into a scenario where the use of MonadError would only be valid if >> catchError (pure a) h = pure a >> was a law, so I looked up the laws in >> https://hackage.haskell.org/package/mtl-2.3/docs/Control-Monad-Error-Class.html#t:MonadError >> but surprisingly found none. >> >> One would expect to see >> 1. catchError (pure a) h = pure a >> 2. catchError (throwError e) h = h e >> 3. throwError e >>= f = throwError e >> >> which would rule out silly instances like >> instance MonadError () Maybe where >> throwError () = Nothing >> catchError _ f = f () >> >> Searching for "monad error laws" gives me no haskell results, only >> https://typelevel.org/blog/2018/04/13/rethinking-monaderror.html which >> suggests the same laws. >> >> I propose adding these 3 laws to MonadError haddocks. >> AFAICT the IO/Maybe/Either/ExceptT instances in >> https://hackage.haskell.org/package/mtl-2.3/docs/src/Control.Monad.Error.Class.html%20 >> all obey the laws. >> _______________________________________________ >> Libraries mailing list >> [email protected] >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > --0000000000009c165605e8482391 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"auto"><div>Sorry, I mangled that. I meant<div dir=3D"auto"><br>= </div><div dir=3D"auto"><div dir=3D"auto">catchError (m >>=3D f) h = =3D catchError (Right <$> m) (pure . Left) >>=3D</div><div dir= =3D"auto">=C2=A0 either h ((`catchError` h)=C2=A0 . f)</div></div><br><br><= div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Fri, Sep= 9, 2022, 8:49 PM David Feuer <<a href=3D"mailto:[email protected]">= [email protected]</a>> wrote:<br></div><blockquote class=3D"gmail_qu= ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex= "><div dir=3D"auto"><div>I agree. These are still insufficient for much rea= soning, however. I would intuitively expect that</div><div dir=3D"auto"><br= ></div><div dir=3D"auto">catchError (m >>=3D f) h =3D catchError (Rig= ht <$> m) (pure . Left) >>=3D</div><div dir=3D"auto">=C2=A0 eit= her throwError ((`catchError` h)=C2=A0 . f)</div><div dir=3D"auto"><br></di= v><div dir=3D"auto">But I have no idea whether all "reasonable" i= nstances obey that.</div><div dir=3D"auto"><br></div><div dir=3D"auto">Is t= here anything useful to say about the case when the argument to mapError is= sufficiently nice (a monad morphism with some extra property, for instance= ?</div><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_qu= ote" dir=3D"auto"><div dir=3D"ltr" class=3D"gmail_attr">On Fri, Sep 9, 2022= , 5:43 PM Alexandre Esteves <<a href=3D"mailto:alexandre.fmp.esteves@gma= il.com" rel=3D"noreferrer noreferrer" target=3D"_blank">alexandre.fmp.estev= [email protected]</a>> wrote:<br></div><blockquote class=3D"gmail_quote" styl= e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div di= r=3D"ltr">I ran into a scenario where the use of MonadError would only be v= alid if=C2=A0<div>=C2=A0 catchError (pure a) h =3D pure a<br></div><div>was= a law, so I looked up the laws in=C2=A0<a href=3D"https://hackage.haskell.= org/package/mtl-2.3/docs/Control-Monad-Error-Class.html#t:MonadError" rel= =3D"noreferrer noreferrer noreferrer" target=3D"_blank">https://hackage.has= kell.org/package/mtl-2.3/docs/Control-Monad-Error-Class.html#t:MonadError</= a> but surprisingly found none.</div><div><br></div><div>One would expect t= o see</div><div>=C2=A0 1.=C2=A0catchError (pure a) h =3D pure a<br>=C2=A0 2= . catchError (throwError e) h =3D h e<br></div><div>=C2=A0 3. throwError e = >>=3D f =3D throwError e</div><div><br></div><div>which would rule ou= t silly instances like</div><div>=C2=A0 instance MonadError () Maybe where<= br>=C2=A0 =C2=A0 throwError () =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D Nothing<br>= =C2=A0 =C2=A0 catchError _ f =3D f ()<br></div><div><br></div><div>Searchin= g for "monad error laws" gives me no haskell results, only <a hre= f=3D"https://typelevel.org/blog/2018/04/13/rethinking-monaderror.html" rel= =3D"noreferrer noreferrer noreferrer" target=3D"_blank">https://typelevel.o= rg/blog/2018/04/13/rethinking-monaderror.html</a> which suggests the same l= aws.</div><div><br></div><div>I propose adding these 3 laws to MonadError h= addocks.</div><div>AFAICT the IO/Maybe/Either/ExceptT instances in <a href= =3D"https://hackage.haskell.org/package/mtl-2.3/docs/src/Control.Monad.Erro= r.Class.html%20" rel=3D"noreferrer noreferrer noreferrer" target=3D"_blank"= >https://hackage.haskell.org/package/mtl-2.3/docs/src/Control.Monad.Error.C= lass.html%20</a> all obey the laws.</div></div> _______________________________________________<br> Libraries mailing list<br> <a href=3D"mailto:[email protected]" rel=3D"noreferrer noreferrer noref= errer" target=3D"_blank">[email protected]</a><br> <a href=3D"http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel= =3D"noreferrer noreferrer noreferrer noreferrer" target=3D"_blank">http://m= ail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br> </blockquote></div></div></div> </blockquote></div></div></div> --0000000000009c165605e8482391-- --===============8794242309512341912== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KTGlicmFyaWVz IG1haWxpbmcgbGlzdApMaWJyYXJpZXNAaGFza2VsbC5vcmcKaHR0cDovL21haWwuaGFza2VsbC5v cmcvY2dpLWJpbi9tYWlsbWFuL2xpc3RpbmZvL2xpYnJhcmllcwo= --===============8794242309512341912==--