看看一些Writer monad示例,在“学习一个Haskell”的例子中,我不知道在何处重载了在最后一行表达式中使用*乘法运算符来处理由logNumber函数生成的Writer对象:
import Control.Monad.Writer
logNumber :: Int -> Writer [String] Int
logNumber x = Writer (x, ["Got number: " ++ show x])
multWithLog :: Writer [String] Int
multWithLog = do
a <- logNumber 3
b <- logNumber 5
return (a*b)发布于 2022-09-27 21:22:15
这里似乎有些误会。在示例代码中:
import Control.Monad.Writer
logNumber :: Int -> Writer [String] Int
logNumber x = Writer (x, ["Got number: " ++ show x])
multWithLog :: Writer [String] Int
multWithLog = do
a <- logNumber 3
b <- logNumber 5
return (a*b)值a和b不是Writer值。它们的类型只是Int,当然可以乘2 Ints。因此a*b也是一个Int --请注意最后一行中return的使用,这里需要使用return才能将Int类型的“普通值”a*b“提升到Writer [String] Int类型的”一元值“。
logNumber 3当然是一个一元值(类型为Writer [String] Int),但是do表示法中的<-语法糖“提取”了它的底层值,并给它起了一个名字--这里是a。更准确地说,上面的do块可以:
multWithLog = logNumber 3 >>= \a -> logNumber 5 >>= \b -> return (a*b)其中lambda表达式的类型为Int -> Writer [String] Int (参数a和b为所讨论的Ints ),由于>>=的类型,>>=将生成一个Writer [String] Int类型的表达式。
https://stackoverflow.com/questions/73873884
复制相似问题