2014-10-16 31 views
8

下面的代码,这是verbatim from LYAH,不编译编译作家单子例子。代码和编译时错误包含在下面。在LYAH页,代码〜15%下跌的一页,耶emacs的浏览器:)无法从“学习你Haskell的”

任何想法,为什么?我忽略了一些完全明显的东西?

(尽管在后头衔的相似性,我想我的问题是从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. 

回答

14

LYAH过时了t他的榜样。您应该使用writer智能构造函数方法而不是(现在不存在的)Writer数据构造函数。

要扩大一点,这些数据类型分别更新为与单子变压器的兼容性更好。其结果是,有一个一般WriterT,用于在单子变压器叠层使用,而且构成与WriterT一个Identity类型Writer同义词。因此,不再有与​​Writer类型专门关联的数据构造函数(因为Writer是类型的同义词)。

幸运的是,尽管这种并发症,解决方案很简单:用writer更换Writer

+0

我想这是我乐观的认为,与'writer'更换'Writer'会得到它运行:)这样做的结果在'multWithLog'函数的下列错误中(以及'logNumber'函数的类似错误):'没有从do语句引起的(Monad(writer [String])的实例)。我会继续玩。 – iceman 2014-10-16 22:57:59

+11

@DipakC保留类型签名相同。通过调用'writer'来替换函数调用'Writer'。类型签名中的小写起始字母总是指一个类型变量,这不是我们想要的。我们需要具体的类型'Writer'。 – 2014-10-16 22:59:28

+1

我的意思是,谁不想要一台具体的打字机? – N3dst4 2017-10-10 12:01:53

0

在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)