[Haskell-cafe] Generalized monadic exception handling with monad-peel

Bas van Dijk v.dijk.bas at gmail.com
Wed Nov 3 09:13:48 EDT 2010


On Wed, Nov 3, 2010 at 10:59 AM, Anders Kaseorg <andersk at mit.edu> wrote:
> I just released the monad-peel library to Hackage.

This is great news!

My regions library uses 'bracket' from MonadCatchIO in the runRegionT
function. Due to the recent discussion on MonadCatchIO I realized that
users could hack around the safety guarantees of the library by
inserting an Error monad somewhere in the stack of monad transformers
of a RegionT. Then they could do something like:

runRegionT $ do
  h <- openFile "file.txt" ReadOnly
  throwError "die!"

which then won't close h! This obviously breaks the safety guarantees
of my regions library.

I will update the regions library and related packages with your
monad-peel. Thanks!

Something else: In the soon to be released base-4.3 the block and
unblock functions will be deprecated in favor of mask. It would be
great if you can also add these new functions to
Control.Exception.Peel:

import qualified Control.Exception as CE (mask, mask_, uninterruptibleMask)

#if MIN_VERSION_base(4,3,0)
-- |Generalized version of 'CE.mask'. Note, any monadic side
-- effects in @m@ of the \"restore\" computation will be discarded; it
--  is run only for its side effects in @IO at .
mask :: MonadPeelIO m => ((forall a. m a -> m a) -> m b) -> m b
mask f = do
  k <- peelIO
  join $ liftIO $ CE.mask $ \restore -> k $ f $ liftIOOp_ restore

-- |Generalized version of 'CE.mask_'.
mask_ :: MonadPeelIO m => m a -> m a
mask_ = liftIOOp_ CE.mask_

-- |Generalized version of 'CE.uninterruptibleMask'. Note, any monadic side
-- effects in @m@ of the \"restore\" computation will be discarded; it
--  is run only for its side effects in @IO at .
uninterruptibleMask :: MonadPeelIO m => ((forall a. m a -> m a) -> m b) -> m b
uninterruptibleMask f = do
  k <- peelIO
  join $ liftIO $ CE.uninterruptibleMask $ \restore -> k $ f $ liftIOOp_ restore
#endif

You have to review these definitions carefully; I'm not yet fully
comfortable with peelIO.

Finally, would you also like to add wrapped functions for alloca and
friends from all the Foreign modules?

Regards,

Bas


More information about the Haskell-Cafe mailing list