🎓 A1Learner
🔍
0 of 50 lessons completed

Haskell Lift

Lift runs an action from the inner monad inside a transformer layer. It lifts the inner action up into the outer layer.

Lift prints from inside ReaderT

The block asks for 33 and lifts a print of that value. The printed number is 33.

import Control.Monad.Trans.Reader
import Control.Monad.Trans.Class
main :: IO ()
main = runReaderT (do n <- ask; lift (print n)) 33

Lift prints from inside StateT

The block prints its starting state of 40, then moves it to 41. The main program prints the final state next.

import Control.Monad.Trans.State
import Control.Monad.Trans.Class
main :: IO ()
main = do
  (_, final) <- runStateT (do n <- get; lift (print n); put (n + 1)) 40
  print final

Lift can bring a value into the layer

The block lifts the plain value 7, adds the shared value 3, and returns 10.

import Control.Monad.Trans.Reader
import Control.Monad.Trans.Class
main :: IO ()
main = do
  result <- runReaderT (do x <- lift (return 7); n <- ask; return (x + n)) 3
  print result

Example

import Control.Monad.Trans.Reader
import Control.Monad.Trans.Class
main :: IO ()
main = runReaderT (do name <- ask; lift (putStrLn name); lift (print (length name))) "Romi"

Key points

  • Lift: a function that runs an inner-monad action inside a transformer layer.
  • Use lift to run an IO action inside ReaderT over IO.
  • Use lift to run an IO action inside StateT over IO.
  • A lifted action keeps its own effect while the outer layer stays in place.
  • An inner action needs lift before it can run in the outer layer.

In this example, the block asks for the name Romi, lifts a print of the name, and then lifts a print of its length. Both prints come from IO, lifted into the ReaderT layer.

Note

lift comes from Control.Monad.Trans.Class.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Haskell Playground

Exercise

Why does an IO action inside ReaderT over IO need lift?