
From: Yitzchak Gale
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, http://hackage.haskell.org/package/MonadCatchIO-mtl ? 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 with 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. John