[EMAIL PROTECTED] 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.
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe