在 ghci 中使用 Writer monad 的问题

wal*_*ers 3 monads haskell

我目前正在通过《Learn You a Haskell for Great Good》这本书来学习 Haskell,并坚持使用Log NumberGreatest Common Divisor介绍Writermonad的脚本。我了解它们的作用,但加载它们会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)
Run Code Online (Sandbox Code Playgroud)
 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])
  |               ^^^^^^
Run Code Online (Sandbox Code Playgroud)

我不知道为什么会发生这种情况,因为我从示例中复制了代码。代码有问题吗?还是Control.Monad.Writer书出版后图书馆发生了变化?我该如何修复代码?

我使用haskell-platformghc 8.6.5

bra*_*drn 7

已在Control.Monad.Writer库改变,因为这本书出版?

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