【发布时间】:2016-02-26 04:41:40
【问题描述】:
我正在学习《Learn You A Haskell》一书中的 Writer Monad。
这是一段代码:
import Control.Monad.Writer
logNumber :: Int -> Writer [String] Int
logNumber num = writer (num, ["Got number: " ++ show num])
multWithLog :: Writer [String] Int
multWithLog = do
a <- logNumber 3
b <- logNumber 5
return (a * b)
运行multWithLog时,结果如下:
*Main> runWriter multWithLog
(15,["Got number: 3","Got number: 5"])
在这一行:
a <- logNumber 3
b <- logNumber 5
很容易看出a = 3 和b = 5,因为它们都在return 函数上相乘。
我不明白为什么这些值是3 和5。 a 和 b 不应该是包含在 Writer Monad 中的值吗?在这种情况下是元组?
例如,对于 Maybe Monad,a 和 b 将是 3 和 5:
do
a <- Just 3
b <- Just 5
return (a * b)
在这种情况下,这对我来说是有意义的,因为 a 和 b 接收到 Just 中的内容。但对于最初的示例,a 和 b 只接收部分值。
【问题讨论】:
-
当您在
Writermonad 中执行x <- e时,x通常不会捕获编写器状态。您可以将 logNumber 重写为logNumber num = tell "..." >> return num- 这是一个产生与给出的相同数字的计算,但作为副作用“记录”一个字符串。当您“绑定”时,您正在访问“返回”的值 - 这只是数字。您可以使用listen:(x,loggedString) <- listen $ logNumber 3获得所需的行为。
标签: haskell monads writer-monad