[Haskell-cafe] Re: Control.Exceptions and MonadIO
Brian Hulley
brianh at metamilk.com
Sun Apr 23 14:19:18 EDT 2006
oleg at pobox.com wrote:
> Robert Dockins wrote:
>> One additional (very unfortunate) point is that higher-order IO monad
>> combinators will not work on your monad, eg, the ones in
>> Control.Exception.
>
> Although that is true in general, for many useful and interesting
> cases (including ReaderT, the state transformer, and the newtype
> wrapping of IO) one _can_ use catch, bracket etc. constructs in
> MonadIO. Please see this message and the follow-up discussion:
>
> http://www.haskell.org/pipermail/haskell/2006-February/017547.html
If it is true that it is absolutely impossible to implement
Control.Exception for any MonadIO (it would be useful to know why cf the old
saying "there is no such word as can't"), the other option seems to be to
re-organise Control.Exception to make use of different monads that could
support the various subsets of operations, as you've begun in the thread
above by defining CaughtMonadIO.
Perhaps something like:
class MonadIO m => MonadIOE m where
catch :: m a-> (Exception -> m a) -> m a
throw
catchDyn
throwDyn
-- etc
instance MonadIOE m => StateT s m where ...
instance MonadIOE m => ReaderT r m where ...
blockIO :: IO a -> IO a
class MonadIO m => MonadIOB m where
getUnliftIO :: m (m a -> IO a)
block :: m a -> m a
block x = do
unliftIO <- getUnliftIO
liftIO (blockIO (unliftIO x))
unblock :: m a -> m a
bracket_ :: m a -> m b -> m c -> m c
-- etc
instance MonadIOB m => ReaderT r m where ...
and then we could just get rid of all the other exception handling functions
scattered all over the code base eg Prelude.catch etc.
StateT s can be an instance of MonadIOE but not of MonadIOB because although
it is sometimes fine to discard state changes when an exception arises, it
is not ok to discard the state changes inside a block (or unblock, bracket_
etc).
Does the above look like a good way of organising things?
(I don't know whether MonadIOB would require MonadIOE or not since I haven't
tried to implement all these functions yet - if it did I would use the name
MonadIOEB instead)
I'm about to make an attempt along these lines myself since I can't go
further in my own work without a proper exception api that doesn't drag
everything down to concrete IO (unless someone else has already done this?)
Also, would it be worth modifying
http://hackage.haskell.org/trac/haskell-prime/ticket/110 to include
something like this (someone more knowledgeable than me would have to do
it)?
Regards, Brian.
More information about the Haskell-Cafe
mailing list