2013-05-15 30 views
1

在下面的Haskell代碼中,函數typeError不會檢查類型。Haskell函數組成 - 錯誤推斷類型

wrap x = [x] 

listf :: [[a]] -> [[a]] 
listf = id 

typeCheck :: [a] -> [[a]] 
typeCheck x = listf (wrap x) 

typeError :: [a] -> [[a]] 
typeError = wrap . listf 

GHC產生這個錯誤,如果它是未註釋:

Couldn't match type `a' with `[a0]' 
    `a' is a rigid type variable bound by 
     the type signature for typeError :: [a] -> [[a]] at tim.hs:10:1 
Expected type: [a] -> [a] 
    Actual type: [[a0]] -> [[a0]] 
In the second argument of `(.)', namely `listf' 
In the expression: wrap . listf 

我不明白爲什麼。 a應該能夠與[a0]一致 - 它們是獨立的類型變量。這正是它爲typeCheck推斷的類型 - 但在使用.運算符時不適用。

擁抱產生非常相似的,並且類似地雜散,錯誤消息:

ERROR "repro.hs":10 - Inferred type is not general enough 
*** Expression : typeError 
*** Expected type : [a] -> [[a]] 
*** Inferred type : [[a]] -> [[[a]]] 

此外,該正常工作:

listf' :: [a] -> [a] 
listf' = id 

typeCheck' :: [a] -> [[a]] 
typeCheck' = wrap . listf' 

該問題只與[[一個]或發生[ [[a]]]或更高。這裏的交易是什麼?

回答

5

你似乎在這裏顛倒了功能組合。

-- This 
typeCheck :: [a] -> [[a]] 
typeCheck x = listf (wrap x) 

-- is the same as 
typeCheck' :: [a] -> [[a]] 
typeCheck' = listf . wrap 

-- while this 
typeError :: [a] -> [[a]] 
typeError = wrap . listf 

-- is the same as 
typeError' :: [a] -> [[a]] 
typeError' x = wrap (listf x) 

現在它應該有希望是顯而易見的爲什麼這不起作用。 listf要求其參數是[[a]],但typeError的簽名聲稱它適用於任何[a]

+0

該死的,這就是我在嘗試修復這個代碼中的一個錯誤後得到的,經過多年的不做Haskell ..謝謝。 – banana