
On 04/19/10 02:15, Anders Kaseorg wrote:
I would be very happy to get the simpler interface to work, because it’s Haskell 98. However, if I write joinIO m = morphIO (\w -> m>>= w) morphIO' f = joinIO (f return) and define catch using morphIO' instead of morphIO: m `catch` h = morphIO $ \w -> w m `Control.Exception.catch` \e -> w (h e) m `catch'` h = morphIO' $ \w -> w m `Control.Exception.catch` \e -> w (h e) then catch' fails to actually catch anything:
*Main> throwIO NonTermination `catch` \NonTermination -> return "moo" "moo" *Main> throwIO NonTermination `catch'` \NonTermination -> return "moo" *** Exception:<<loop>>
Am I doing something wrong?
Well, let's see what happens if we apply it to the fairly easy
instance MonadMorphIO IO where morphIO f = f id
then joinIO m = morphIO (\w -> m >>= w) = (\w -> m >>= w) (id) = m >>= id = join m morphIO' f = joinIO (f return) = join (f return) morphIO = f id m `catch` h = morphIO $ \w -> w m `Control.Exception.catch` \e -> w (h e) [w = id] = id m `Control.Exception.catch` \e -> id (h e) m `catch'` h = morphIO' $ \w -> w m `Control.Exception.catch` \e -> w (h e) [w = return] = join (return m `Control.Exception.catch` \e -> return (h e)) Do you see the difference? The effects are sequenced in different places. The return/join pair moves all the effects *outside* the operations such as catch... thus defeating the entire purpose of morphIO. -Isaac