In the following code snippet, return/pure
cannot work as it constructs StateT s IO (IO ())
, not StateT s IO ()
.
return/pure
will construct the value based on the currect monad in context, which is StateT s IO
. lift
will upgrade the
current monad(IO
) to the new monad through the transformer.
printState :: Show s => StateT s IO ()
printState = do
state <- get
-- print state fails due to IO () doesn't match to StateT s
-- so you could liftIO, lift also can work due to the StateT
-- pure/return cannot work as, due to you `StateT s IO` is the new monad,
-- and you want to return the IO () to it
-- Expected: StateT s IO ()
-- Actual: StateT s IO (IO ())
-- lift means, use the current monad to construct the new monad
lift $ print state