2012-04-23 73 views
5

我碰到了一些我在使用Haskell交互提示(ghci)時發現好奇的東西。下ghci中運行下面的代碼7.0.4帶有數字的類型歧義

[minBound..1] 

拋出以下異常:

<interactive>:1:12: 
    Ambiguous type variable `t0' in the constraints: 
     (Num t0) arising from the literal `1' at <interactive>:1:12 
     (Enum t0) arising from the arithmetic sequence `minBound .. 1' 
       at <interactive>:1:1-13 
     (Bounded t0) arising from a use of `minBound' 
        at <interactive>:1:2-9 
    Probable fix: add a type signature that fixes these type variable(s) 
    In the expression: 1 
    In the expression: [minBound .. 1] 
    In an equation for `it': it = [minBound .. 1] 

我知道,寫了上爲[minBound..1 :: INT]就明確指出「 1'的意思是Int,但我的問題是,歧義在哪裏? 「1」可以被解釋爲詮釋整數浮動,但這些都不只是詮釋屬於類。那麼還有另外一個可以僞裝成字面的類嗎?如果不是,那麼什麼?

回答

10

defaulting rules,受約束的類型變量試圖通過默認來解決,如果

  • 所有約束的形式爲C a; a不作爲約束中類型構造函數的參數出現,並且至少涉及的其中一個類是數字類,並且所有類都在Prelude或標準庫中定義。

推斷型表達[minBound .. 1]的是

[minBound .. 1] :: (Num a, Enum a, Bounded a) => [a] 

所以默認規則適用。但對於違約,只有在默認聲明模塊的被認爲是列出的類型 - 在不存在默認聲明中,缺省默認假定的(Integer, Double),即以解決受約束曖昧型變量,第一Integer試圖,如果不滿足所有約束,則嘗試Double。如果這還不能滿足所有約束條件,則默認失敗,並且編譯失敗,並顯示ambiguous type variable錯誤¹。

在這種情況下,IntegerDouble都不符合Bounded約束條件,因此違約失敗。

¹在ghci中,或與ExtendedDefaultRules擴展啓用,默認如果沒有數字類是限制因素,但Show是,默認的缺省值由()延長,也會嘗試。

+0

很好的答案,謝謝;我正在假設Haskell的類型推斷是如何工作的,現在我知道的更好 – Aky 2012-04-23 21:05:14