无法编译来自“了解你的Haskell”的Writer Monad示例

时间:2014-10-16 22:43:23

标签: haskell monads

以下代码verbatim from LYAH无法编译。代码和编译时错误包含在下面。在LYAH页面上,代码在页面下方约15%,yay emacs浏览器:)

任何想法为什么?我忽略了一些非常明显的事情吗?

(尽管后期标题相似,但我认为我的问题与this one不同。)


这是代码(在我命名为testcopy.hs的文件中)

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)

这是编译时错误:

Prelude> :l testcopy.hs
[1 of 1] Compiling Main             ( testcopy.hs, interpreted )
testcopy.hs:4:15:
    Not in scope: data constructor `Writer'
    Perhaps you meant `WriterT' (imported from Control.Monad.Writer)
Failed, modules loaded: none.

2 个答案:

答案 0 :(得分:16)

LYAH在这个例子中已经过时了。您应该使用writer智能构造函数方法而不是(现在不存在的)Writer数据构造函数。

为了扩展一点,这些数据类型被更新为与monad变换器更兼容。因此,在monad变换器堆栈中使用通用WriterT,并使用Writer类型同义词将WriterTIdentity组合在一起。因此,不再有专门与Writer类型相关联的数据构造函数(因为Writer是类型同义词)。

幸运的是,尽管存在这种复杂情况,但解决方案非常简单:将Writer替换为writer

答案 1 :(得分:1)

GHC 7.10.3中的正确版本应该是这样的

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)