在 ghci 中使用 Writer monad 的问题

Problems using Writer monad in ghci

我目前正在学习 Haskell 这本书 向你学习 Haskell 好书 并被 的脚本所困Log NumberGreatest Common Divisor 引入了 Writer monad。我了解它们的作用,但将它们加载到 ghci 会导致错误。参见:http://learnyouahaskell.com/for-a-few-monads-more#writer

下面是 logNumber 脚本和我得到的错误代码:

-- Log Number
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)
 error:
    * Data constructor not in scope:
        Writer :: (Int, [[Char]]) -> Writer [String] Int
    * Perhaps you meant one of these:
        `WriterT' (imported from Control.Monad.Writer),
        variable `writer' (imported from Control.Monad.Writer)
  |
5 | logNumber x = Writer (x, ["Got number: " ++ show x])
  |               ^^^^^^

我不知道为什么会这样,因为我从示例中复制了代码。代码有问题吗?或者自本书出版以来 Control.Monad.Writer 库是否发生了变化?我该如何修复代码?

我正在使用 haskell-platformghc 8.6.5

Has the Control.Monad.Writer library changed since the book was published?

是的,就是这个问题。自 LYAH 发布以来,Writer monad 已更改;它不是自己的数据类型,而是根据 monad 转换器 WriterT 定义的。 Monad 转换器真的很有用,这一变化提供了更多的灵活性,但这也意味着所有旧教程都不再正确。您可以通过使用 writer 函数而不是 Writer 构造函数来解决此问题:它们具有相同的类型,但是 writer 是根据新的 WriterT 类型实现的现已删除的 Writer 构造函数。