blame: mtl MonadReader instance for ContT

Chung-chieh Shan ccshan at
Thu Jan 1 00:56:16 EST 2009

Nicolas Frisby <nicolas.frisby at> wrote in article <5ce89fb50812291016oda99984u480414f4c9675f25 at> in gmane.comp.lang.haskell.libraries:
> I did come across that. They only call this particular lifting "not
> natural," which doesn't seem much of a justification - unless they
> mean natural in a more formal sense that isn't immediately obvious to
> me.

I agree it's not much of a justification.  Maybe what they meant by
"natural" is that the same code (using "ask" and "local") should work in
the reader monad as in the continuation monad transformer applied to the
reader monad.  Here's an example to illustrate:

    import Control.Monad.Cont
    import Control.Monad.Reader

    example local = do
        x <- ask
        y <- local (1+) ask
        z <- ask
        return (x,y,z)

    local' f m = ContT $ \c -> do
        r <- ask
        local f (runContT m c)

In ghci 6.8.2, I get

    *Main> runReader (runContT (example local) return) 1
    *Main> runReader (runContT (example local') return) 1

> I revisited that paper upon finding the reference in your Delimited
> Dynamic Binding, the examples of which finally lent some clarity to
> the differences in the computational behaviors I was dealing with.

Thanks for the encouragement. (:

Edit this signature at
100 Days to close Guantanamo and end torture

More information about the Libraries mailing list