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