Monad 与 Monad 变形金刚

Monad vs Monad transformers

"Monads allow the programmer to build up computations using sequential building blocks" 因此它允许我们结合一些计算。如果是这样,那为什么下面的代码不能运行呢?

import Control.Monad.Trans.State

gt :: State String String
gt = do
   name <- get
   putStrLn "HI" -- Here is the source of problem!
   put "T"
   return ("hh..." ++ name ++ "...!")


main= do
  print $ execState gt "W.."
  print $ evalState gt "W.."

Monad 转换器 将不同函数放入 monad 的机制。

monad 只知道如何组合在该 monad 能力范围内的计算。您不能在 State monad 中执行 I/O,但可以在 StateT s IO a monad 中执行。但是,您需要在执行 I/O.

的计算中使用 liftIO
import Control.Monad.Trans.State
import Control.Monad.IO.Class (liftIO)

gt :: StateT String IO String
gt = do
   name <- get
   liftIO $ putStrLn "HI"
   put "T"
   return ("hh..." ++ name ++ "...!")


main = do
  print =<< execStateT gt "W.."
  print =<< evalStateT gt "W.."