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 中(像上面的例子)?
为什么我们需要一个额外的层,即 transformers 来组合 monads?
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.."
"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 中(像上面的例子)?
为什么我们需要一个额外的层,即 transformers 来组合 monads?
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.."