
On Thu, Oct 14, 2010 at 7:15 AM, Michael Snoyman
By the way, here is how I would implement the ErrorT MonadCatchIO instance:
instance (MonadCatchIO m, Error e) => MonadCatchIO (ErrorT e m) where m `catch` f = mapErrorT (\m' -> m' `catch` \e -> runErrorT $ f e) m block = mapErrorT block unblock = mapErrorT unblock bracket before after thing = block $ do a <- before unblock $ thing a `finally` after a bracket_ before after thing = block $ do _ <- before unblock $ thing `finally` after finally thing after = mapErrorT (`finally` runErrorT after) thing
By using "finally" inside of the definitions of bracket, bracket_ and finally, we can ensure that if there is any "special" monad underneath our ErrorT, the cleanup function will still run.
Michael
A while back I wrote a small package built on MonadCatchIO to give the equivalent of alloca and the like[1]. I haven't used it much because I couldn't convince myself that the resources would eventually be freed in a monad with non-standard control flow (such as the continuation based iteratee-0.4[2]). Antoine [1] http://hackage.haskell.org/packages/archive/MonadCatchIO-mtl-foreign/0.1/doc... [2] http://hackage.haskell.org/package/iteratee