Ryan Ingram
Wed, 08 Apr 2009 17:29:41 -0700
On Wed, Apr 8, 2009 at 11:22 AM, Sebastian Fischer
<s...@informatik.uni-kiel.de> wrote:
>> newtype ContT t a = ContT { unContT :: forall r . (a -> t r) -> t r }
>>
>> instance Monad (ContT t)
>> where
>> return x = ContT ($x)
>> m >>= f = ContT (\k -> unContT m (\x -> unContT (f x) k))
> Both the `mtl` package and the `transformers` package use the same > `Monad` instance for their `ContT` type but require `t` to be an > instance of `Monad`. Why? [^1] You are missing one important piece of the puzzle for ContT: > lift :: Monad m => m a -> ContT m a > lift m = ContT $ \k -> m >>= k This >>= is the bind from the underlying monad. Without this operation, it's not very useful as a transformer! Without lift, it's quite difficult to get effects from the underlying Applicative *into* ContT. Similarily, your MonadPlus instance would be just as good replacing with the "free" alternative functor: data MPlus a = Zero | Pure a | Plus (MPlus a) (MPlus a) and then transforming MPlus into the desired type after runContT; it's the embedding of effects via lift that makes ContT useful. The CPS transfrom in ContT also has the nice property that it makes most applications of >>= in the underlying monad be right-associative. This is important for efficiency for some monads; especially free monads; the free monad discussed by jcc has an O(n^2) running cost for n left-associative applications of >>=. -- ryan _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe