[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
class.
The subject of catching errors in non-IO monads has a long history,
some of which is documented at
http://okmij.org/ftp/Haskell/index.html#catch-MonadIO
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:
http://okmij.org/ftp/Haskell/CaughtMonadIO.lhs
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
suffice.
More information about the Haskell-Cafe
mailing list