Move MonadIO to base

John Lato jwlato at
Mon Apr 12 08:05:15 EDT 2010

> From: Yitzchak Gale <gale at>
> Twan van Laarhoven wrote:
>> If MonadIO were in base, then the base library itself could also use it. For
>> example the functions in System.IO could be lifted to work on any MonadIO
>> monad. Whether that is a good idea is completely orthogonal to this
>> discussion, however.
> The main problem is that exceptions don't work well with
> MonadIO in GHC. So really MonadIO is currently only a toy and
> cannot be used in production code.
> The reason for this is that just about any operation involving exceptions
> ultimately depends (via the source code of base library functions)
> on the function
> block :: IO a -> IO a

What about the approach used in MonadCatchIO, ?

The MonadCatchIO class has two functions "block" and "unblock", which
are implemented as e.g.

instance MonadCatchIO IO where
    catch   = E.catch
    block   = E.block
    unblock = E.unblock

instance MonadCatchIO m => MonadCatchIO (ReaderT r m) where
    m `catch` f = ReaderT $ \r -> (runReaderT m r)
                                    `catch` (\e -> runReaderT (f e) r)
    block       = mapReaderT block
    unblock     = mapReaderT unblock


mapReaderT :: (m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT f m = ReaderT $ f . runReaderT m

To my eye this solves the problem of "block" and "unblock" being
baked-in to GHC, because they will be applied through the stack to the
underlying IO operations as the user would expect.  I could be
mistaken, though.

If this approach is correct and MonadIO is moved to base, I would
think that "block" and "unblock" at least should be added to MonadIO.


More information about the Libraries mailing list