Move MonadIO to base

Isaac Dupree ml at isaac.cedarswampstudios.org
Mon Apr 19 02:41:54 EDT 2010


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


More information about the Libraries mailing list