2014-10-16 39 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)