
On Mon, 2009-01-19 at 13:03 -0800, Daryoush Mehrtash wrote:
Is there a reason why the lift function in ReaderT's MonadTrans instance is implemented as:
instance MonadTrans (ReaderT r) where
lift m = ReaderT $ \_ -> m
Instead of just using the monad's return function? Could "lift m" be implemented as "return m"?
No: Prelude> :m + Control.Monad.Reader Prelude Control.Monad.Reader> :t \ m -> ReaderT $ \ _ -> m \ m -> ReaderT $ \ _ -> m :: m a -> ReaderT r m a Prelude Control.Monad.Reader> :t \ m -> ReaderT $ \ _ -> return m \ m -> ReaderT $ \ _ -> return m :: (Monad m) => a -> ReaderT r m a Your first clue that something's wrong should be that the types don't work out. (On the other hand, your hunch that lift = return is correct --- so you get a cookie for that; it's just that return here is neither the return of the monad for m nor the return of the monad for ReaderT m. It is, instead, the return of the *applicative functor* --- on the category of monads and monad homomorphisms --- associated to the monad transformer ReaderT.) (By the way, you *do* have the equations lift (return x) = return x and lift (a >>= f) = lift a >>= lift . f ) jcc