2014-05-04 27 views
0

有麻煩林推斷這個函數的類型:推斷類型組成功能的哈斯克爾

(foldr (.)) 

我知道類型:

(.) :: (b -> c) -> (a -> b) -> a -> c 

foldr :: (a -> b -> b) -> b -> [a] -> b 

但現在我不知道該怎麼做..有沒有一種方法可以始終以系統的方式推斷出類型?它如何適用於這種情況?

+0

你可以問ghci的:使用': t' – jev

+2

[派生類型(foldr(。))](http://stackoverflow.com/questions/23417844/deriving-the-type-of-foldr) –

回答

4

我通常遵循以下步驟:

寫它們的類型:

(.) :: (b -> c) -> (a -> b) -> a -> c 
foldr :: (a -> b -> b) -> b -> [a] -> b 

進行所有類型變量名稱不同:

(.) :: (b -> c) -> (a -> b) -> a -> c 
foldr :: (x -> y -> y) -> y -> [x] -> y 

現在,因爲你申請(.)第一個參數的foldr,可以推斷出以下幾種關係:

foldr :: ( x ->  y ->   y ) -> y -> [x] -> y 
(.) :: (b -> c) -> (a -> b) -> (a -> c) 

從上面可以推斷以下關係:

x ~ (b -> c) 
y ~ (a -> b) 
y ~ (a -> c) 

從上面y,您可以推斷出兩個bc應該是相同的。

類型的foldr (.)應該是:

foldr (.) :: y -> [x] -> y 

現在更換yx新派生的,你會得到所需要的類型:

foldr (.) :: (a -> b) -> [b -> b] -> a -> b 
+0

可能的重複非常感謝您的解釋。我唯一的問題是,你怎麼知道在哪裏放置括號?通過這個我的意思是,你不能括號表達,以便x〜b,y〜c-> a-> b,y〜a-> c。在這種情況下,類型推斷是完全不同的。 – gonza1207

+0

@ user3558296這是因爲'(。)'的​​類型是'(b - > c) - >(a - > b) - > a - > c'。括號部分已經被固定爲'(。)'。 – Sibi

+0

非常感謝我現在得到它..現在我試圖用你解釋的方法來推斷(。flip)的類型,並得到:[code](b - > a - > c1 - > c) - > a - > b - > c1 - > c [/ code]但是ghci說類型是[code]((b - > a - > c1) - > c) - >(a - > b - > c1) - > c [/ code]爲什麼ghci用括號括起b-> a-> c1表達式? – gonza1207