Haskell: lift vs liftIO

Lachlan picture Lachlan · Oct 13, 2010 · Viewed 19k times · Source

In what situations should liftIO be used? When I'm using ErrorT String IO, the lift function works to lift IO actions into ErrorT, so liftIO seems superfluous.

Answer

Roman Cheplyaka picture Roman Cheplyaka · Oct 13, 2010

lift always lifts from the "previous" layer. If you need to lift from the second layer, you would need lift . lift and so on.

On the other hand, liftIO always lifts from the IO layer (which, when present, is always on the bottom of the stack). So, if you have more than 2 layers of monads, you will appreciate liftIO.

Compare the type of the argument in the following lambdas:

type T = ReaderT Int (WriterT String IO) Bool

> :t \x -> (lift x :: T)
\x -> (lift x :: T) :: WriterT String IO Bool -> T

> :t \x -> (liftIO x :: T)
\x -> (liftIO x :: T) :: IO Bool -> T