On 12/17/07, Jack Kelly <[EMAIL PROTECTED]> wrote:
>
> > liftIO $ hPutStrLn h "You lose"
> > liftIO $ hFlush h
>
> IO is once again special. For other inner monads, the lift function
> does the same thing. Note also that IO has no transformer and must
> therefore always be the innermost monad.


Actually, this isn't true.  In the case of ReaderT Config IO (), liftIO is
the same as lift.

liftIO exists because it is more general; it works for any monad that is an
instance of "MonadIO", which includes IO, ReaderT r IO, StateT s IO, ReaderT
r (StateT s (ErrorT e IO))), etc.

In the last case, you could write
    lift $ lift $ lift $ hPutStrLn h "You lose"
but it's much simpler to write
    liftIO $ hPutStrLn h "You lose"

Similarily, "ask" is defined in the MonadReader typeclass, which includes
Reader, ReaderT IO, and all sorts of other monads that include "Reader" at
some level; only the real "reader" monad has a full implementation; the rest
are defined in terms of "lift" or simpler operations, like so:

instance MonadReader r m => MonadReader r (StateT s m) where
    ask = lift ask
    local f m = StateT $ \s -> local f (runStateT m s)

  -- ryan
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to