
On Wed, Nov 3, 2010 at 10:59 AM, Anders Kaseorg
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@. 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@. 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