Move MonadIO to base

Anders Kaseorg andersk at MIT.EDU
Tue Apr 13 04:26:02 EDT 2010


On Sun, 11 Apr 2010, Bas van Dijk wrote:
> Of course when this change is made the MonadCatchIO class has to be
> adapted to something like:
> 
> class MonadIO m => MonadCatchIO m where
>     catch :: Exception e => m a -> (e -> m a) -> m a
>     mask :: ((m b -> m b) -> m a) -> m a

The striking similarity between instances of MonadCatchIO suggests to me 
that something deeper is going on.  Is there a cleaner abstraction that 
captures this idea?

instance (          MonadCatchIO m) => MonadCatchIO (ReaderT r m) where
    m `catch` f = ReaderT $
        \r   -> runReaderT m r   `catch` \e -> runReaderT (f e) r
    mask io = ReaderT $
        \r   -> mask $ \restore -> runReaderT (io $ mapReaderT restore) r

instance (          MonadCatchIO m) => MonadCatchIO (StateT s m) where
    m `catch` f = StateT  $
        \s   -> runStateT  m s   `catch` \e -> runStateT  (f e) s
    mask io = StateT  $
        \s   -> mask $ \restore -> runStateT  (io $ mapStateT  restore) s

instance (Error e,  MonadCatchIO m) => MonadCatchIO (ErrorT e m) where
    m `catch` f = ErrorT  $
                runErrorT  m     `catch` \e -> runErrorT  (f e)
    mask io = ErrorT  $
                mask $ \restore -> runErrorT  (io $ mapErrorT  restore)

instance (Monoid r, MonadCatchIO m) => MonadCatchIO (WriterT r m) where
    m `catch` f = WriterT $
                runWriterT m     `catch` \e -> runWriterT (f e)
    mask io = WriterT $
                mask $ \restore -> runWriterT (io $ mapWriterT restore)

instance (Monoid w, MonadCatchIO m) => MonadCatchIO (RWST r w s m) where
    m `catch` f = RWST    $
        \r s -> runRWST    m r s `catch` \e -> runRWST    (f e) r s
    mask io = RWST    $
        \r s -> mask $ \restore -> runRWST    (io $ mapRWST    restore) r s

instance (          MonadCatchIO m) => MonadCatchIO (ListT m) where
    m `catch` f = ListT   $
                runListT  m      `catch` \e -> runListT   (f e)
    mask io = ListT   $
                mask $ \restore -> runListT   (io $ mapListT   restore)

instance (          MonadCatchIO m) => MonadCatchIO (ContT r m) where
    m `catch` f = ContT   $
        \c ->   runContT  m c    `catch` \e -> runContT   (f e) c
    mask io = ContT   $
        \c ->   mask $ \restore -> runContT   (io $ mapContT   restore) c

(By the way, these last two don’t seem to be in the current MonadCatchIO 
packages.  Any reason why not?)

Anders


More information about the Libraries mailing list