Prelude.catch vs. Exception.catch
Simon Marlow
simonmar@microsoft.com
Tue, 14 May 2002 10:23:37 +0100
> >The idea is
> >that if you want to use Exceptions in their full glory, you:
> ...
> > import qualified Exception
>=20
> I've noticed something a bit unusual about Exception.catch.=20
> It seems it=20
> can't catch "return undefined" by itself. Consider these=20
> values of type=20
> "IO String":
>=20
> iouPure :: IO String;
> iouPure =3D undefined;
>=20
> iouError :: IO String;
> iouError =3D error "error";
>=20
> These aren't even an IO actions, they're simply bottom.=20
> Straightforward=20
> enough. But they _will_ be caught by Exception.catch.
>=20
> iouFail :: IO String;
> iouFail =3D fail "failure";
>=20
> iouEvaluate :: IOString;
> iouEvaluate =3D Exception.evaluate undefined;
>=20
> These two are IO actions that "fail" when executed. They will also be=20
> caught by Exception.catch.
>=20
> iouReturn :: IO String;
> iouReturn =3D return undefined;
>=20
> This one is an IO action that "succeeds" when executing. It=20
> _won't_ be=20
> caught by Exception.catch, which will instead simply return=20
> the undefined=20
> value.
>=20
> I'm not sure what to make of this...
This is just an artifact of the laziness of 'return'. One of the monad
laws is
return a >>=3D k =3D k a
so therefore
return undefined >>=3D (\_ -> m) =3D m
so return can't be strict. Since return isn't strict,
return undefined `seq` a =3D a
So that's really why we have Exception.evaluate: it's a strict version
of return.
Cheers,
Simon