2013-04-18 31 views
9

我正在學習Haskell,因爲我有一段時間,所以我是一個新手。Haskell多態調用沒有完整的類型知識

下面的代碼是很容易理解的:

purStrLn $ show [1] 

在這裏,我們可以推斷出所有類型(使用默認值),並且一切運作良好。 但是,下面的代碼工作,太:

putStrLn $ show [] 

即使我們不能推斷列表類型。

如果我用ghci的執行代碼中,我得到如下:

Prelude> [] 
[] 
Prelude> :t it 
it :: [a] 
Prelude> 

這樣的類型似乎是多態的。但在這種情況下,節目將以部分應用類型進行調用。

與其他類型相同的行爲是常見的,例如Data.Map.empty,所以它不是列表功能(或者至少看起來像它)。

爲什麼以及它的工作原理?

+0

'purStrLn $顯示[1]'仍然默認爲一個類型, '[1] ::(Num n)=> [n]' – amindfv

+0

確實如此,但在這種情況下有默認值。 – Totoro

+2

請注意,當類型變量不受約束時(例如, 'length []',參見:http://stackoverflow.com/q/7076517。 – hammar

回答

16

首先,這隻適用於ghci。如果你嘗試編譯此程序ghc你會得到一個錯誤類型:

Test.hs:3:19: 
    Ambiguous type variable `a0' in the constraint: 
     (Show a0) arising from a use of `show' 
    Probable fix: add a type signature that fixes these type variable(s) 
    In the second argument of `($)', namely `show []' 
    In the expression: putStrLn $ show [] 
    In an equation for `main': main = putStrLn $ show [] 

添加型簽名使錯誤消失:

module Main where 

main = putStrLn $ show ([]::[Int]) 

但爲什麼它在ghci工作?答案是extended type defaultingghcia的類型默認爲()(單位類型)。

這種行爲的動機是,用戶總是在解釋器中工作時指定類型有點令人厭煩。作爲維圖斯注意到,評論,運行ghci-Wall(或添加:set -Wall~/.ghci)可以更容易地發現瀆職:

<interactive>:2:12: 
    Warning: Defaulting the following constraint(s) to type `()' 
       (Show a0) arising from a use of `show' 
    In the second argument of `($)', namely `show []' 
    In a stmt of an interactive GHCi command: it <- putStrLn $ show [] 
+3

另外,在GHCi中鍵入':set -Wall'有助於發現這種違約。 – Vitus

+0

太棒了,這是一個非常明確的答案:) – Totoro

相關問題