[Haskell-cafe] Re: MonadCatchIO, finally and the error monad

oleg at okmij.org oleg at okmij.org
Fri Oct 15 03:35:22 EDT 2010

Michael Snoyman wrote:
> I have a recommendation of how to fix this: the MonadCatchIO typeclass
> should be extended to include finally, onException and everything
> else. We can provide default definitions which will work for most
> monads, and short-circuiting monads like ErrorT (and I imagine ContT
> as well) will need to override them.

It seems that `finally' can be fixed without all these proposed
additions. The method catch is the only necessary method of the

The subject of catching errors in non-IO monads has a long history,
some of which is documented at


The page points out to an old CaughtMonadIO file. I have just updated
it for new Exceptions, and added the final test:

> test3c go = runErrorT $ go `gfinally` (liftIO $ putStrLn "sequel called")

> test31 = test3c (return "return"         :: ErrorT String IO String)

*CaughtMonadIO> test31
sequel called
Right "return"

> test32 = test3c (error "error"           :: ErrorT String IO String)

*CaughtMonadIO> test32
sequel called
*** Exception: error

> test33 = test3c (throwError "throwError" :: ErrorT String IO String)

*CaughtMonadIO> test33
sequel called
*** Exception: ErrorException "\"throwError\""

As we can see, sequel is always called. Here is the updated file:


Incidentally, one should be very careful of using `finally' with the
continuation monad. The Cont monad lets us ``enter the room once, and
exit many times''. So, finally may be called more than once. We need
the ugly dynamic-wind -- or try to use less powerful monads if they

More information about the Haskell-Cafe mailing list