Proposal: add laws to MonadError

Alexandre Esteves <[email protected]> Fri, 9 Sep 2022 22:42:36 +0100
Newsgroups gmane.comp.lang.haskell.libraries
Message-ID <CAFgV2eb6YxNj5gN5fewc2fTW-FteV9nWKhPS4+KgSNxwb6qiSA@mail.gmail.com>
--===============5397507705073599534==
Content-Type: multipart/alternative; boundary="00000000000045e0d005e8456d63"

--00000000000045e0d005e8456d63
Content-Type: text/plain; charset="UTF-8"

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.

--00000000000045e0d005e8456d63
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I ran into a scenario where the use of MonadError would on=
ly be valid 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.h=
askell.org/package/mtl-2.3/docs/Control-Monad-Error-Class.html#t:MonadError=
">https://hackage.haskell.org/package/mtl-2.3/docs/Control-Monad-Error-Clas=
s.html#t:MonadError</a> but surprisingly found none.</div><div><br></div><d=
iv>One would expect to 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 &gt;&gt;=3D f =3D throwError e</div><div><br></div><=
div>which would rule out silly instances like</div><div>=C2=A0 instance Mon=
adError () 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><b=
r></div><div>Searching for &quot;monad error laws&quot; gives me no haskell=
 results, only <a href=3D"https://typelevel.org/blog/2018/04/13/rethinking-=
monaderror.html">https://typelevel.org/blog/2018/04/13/rethinking-monaderro=
r.html</a> which suggests the same laws.</div><div><br></div><div>I propose=
 adding these 3 laws to MonadError haddocks.</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.Error.Class.html%20">https://hackage.haskell=
.org/package/mtl-2.3/docs/src/Control.Monad.Error.Class.html%20</a> all obe=
y the laws.</div></div>

--00000000000045e0d005e8456d63--

--===============5397507705073599534==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KTGlicmFyaWVz
IG1haWxpbmcgbGlzdApMaWJyYXJpZXNAaGFza2VsbC5vcmcKaHR0cDovL21haWwuaGFza2VsbC5v
cmcvY2dpLWJpbi9tYWlsbWFuL2xpc3RpbmZvL2xpYnJhcmllcwo=

--===============5397507705073599534==--