2014-11-06 81 views
3

TL; DR:什麼會導致GHCi中的類型不匹配錯誤純粹是由於函數組合?這是奇怪地看到GHCI評估以下代碼:Haskell:函數組合導致類型不匹配錯誤

foldl (a . b . c) crackle pop  <- GHCi evaluates this` 

......之後我們試圖評估以下只給一個錯誤:

let snap = a . b . c    <- GHCi evaluates this 
foldl snap crackle pop    <- GHCi reports an error (!) 

較長的版本:

我對我在GHCi觀察到的東西感到困惑,並希望有人能解釋它(描述如下圖所示):

enter image description here

做什麼我們上面看到?:

  • 首先,我們有一個變量b這勢必以下列表:[(2,["Dipak"]), (2,["Andrew"]),(2,["Keone"])]b[(Int,[String])]的類型。 (請參閱第一ghci>提示和在屏幕截圖所得到的輸出的上方。)

  • 然後我們在b執行倍,將其轉化爲以下類型:Map (Integer, [String])。我們通過使用基於insertWith (++)的摺疊功能來實現這種功能,該功能是起始累加器,即empty映射。的功能如下(同下文中上面的屏幕截圖的第二ghci>提示(參見第二ghci>提示上文)

    foldl' (flip $ uncurry (Map.insertWith (++))) (Map.fromList []) b

  • 好的,涼爽;到目前爲止,那麼好

  • 由於上面的foldl'函數是滿口的,我決定組成一個摺疊函數(名字爲foldingFunc),它等於flip $ uncurry (Map.insertWith (++)),這只是上面表達式中的第一個參數foldl'(見let表達式在第三個。提示以上)

  • 這是我感到困惑:作爲常規檢查,我執行相同的foldl'如上,除了與foldingFunc(代替flip $ uncurry (Map.insertWith (++))),它應該簡單地是一個外觀上的改變...現在GHCi報告類型不匹配錯誤(詳情如上)。

有人能幫我理解爲什麼在這種情況下,函數組合導致錯誤(由於類型改變)?我應該做什麼不同?

+2

你打開了「MonomorphismRestriction」嗎? 「b」和「foldingFunc」的類型是什麼? (用ghci中的':t'檢查類型。) – Rufflewind 2014-11-06 05:09:05

+0

賓果遊戲,剛剛關閉它,現在它正常工作。非常感謝。如果你複製粘貼你的評論到一個答案,我會(愉快地!)接受 – iceman 2014-11-06 05:22:33

+0

yatima2975擊敗了我。 :) – Rufflewind 2014-11-06 05:53:27

回答

8

ghci的延長違約規則和可怕的單態限制罷工動態二重奏!

我猜你正在使用稍微過時的ghci,版本爲7.6或更早。

什麼情況是,foldingFunction具有作爲最普遍的類型

foldingFunction :: Ord a => Map a [b] -> (a,[b]) -> Map a [b] 

然而,因爲它是不帶參數的頂層定義和您的ghci的版本仍具有單態的限制,這是不是一個'好'類型(它是多態的,因爲上下文Ord a),並且默認規則啓動了。ghci試圖找到Ord a的默認實例 - 通常這會失敗(因爲沒有類似Num的約束),但ghci也考慮()作爲可能的默認值。這樣的作品,所以,如果你 ghci的爲foldingFunction類型,你會得到

foldingFunction :: Map() [b] -> ((), []) -> Map() [] 

這是你的類型的錯誤來源。 (我希望我已經猜中!)


周圍有這樣的幾種方法:

  1. 添加參數foldingFunction:如果您使用foldingFunction m = (flip $ uncurry (Map.insertWith (++))) m也許更好foldingFunction m (a,bs) = insertWith (++) a bs m它會啓動加工。
  2. 通過在文件頂部添加一個{-# LANGUAGE NoMonomorphismRestriction #-}雜注或通過在ghci的命令行中輸入:set -XNoMonomorphismRestriction以交互方式關閉單態限制。
  3. 升級至更新版本的GHC(7.8.3對我來說無效)。

默認情況下DMR都處於關閉狀態,擴展的默認規則相當近(最近幾年)添加到ghci中,所以甚至可能是因爲您使用的書或文本太舊:)

+1

謝謝!是的,我使用7.6.3 ...時間來更新。 – iceman 2014-11-06 16:53:19