
On April 23, 2010 21:55:52 David Menendez wrote:
N.B. The instance given for ContT does not do what you want. Here's the definition again:
morphIO f = ContT $ \k -> morphIO (\d -> f (\m -> d (runContT m k)))
Note that the entire continuation is passed to d. If you are defining, say, block in terms of morphIO
gblock m = morphIO (\d -> block (d m))
Then m and its continuation get masked, not just m. Similar problems occur for backtracking monads and iteratees.
I think you have to redo ContT so the underlying monad is exposed to the continuation instead of being permanently trapped inside a closure. newtype ContT m a = ContT { runContT :: forall r. (m a -> m r) -> m r } class MorphIO m where morphIO :: (forall b. (m a -> IO b) -> IO b) -> m a instance Monad m => Monad (ContT m) where return x = ContT $ \k -> k $ return x m >>= f = ContT $ \k -> runContT m (>>= \x -> runContT (f x) k) instance MorphIO m => MorphIO (ContT m) where morphIO f = ContT $ \k -> k $ morphIO $ \d -> f $ \m -> d $ runContT m id Now just the single desired computation is being passed to d, which is then re-wrapped and passed onto the continuation. Cheers! -Tyson