2017-08-04 58 views
5

我打了一下,用zipWith和接觸之後:第二個參數如何成爲函數列表?

Prelude Control.Applicative> :t zipWith id 
zipWith id :: [b -> c] -> [b] -> [c] 

爲什麼編譯期待下一個參數的函數列表?

我試圖分析,但不能得出結論,爲什麼下一個參數必須是函數列表。

當我通過idzipWith時,簽名是如何得到應用的?

+5

值得關注的是,這是更常見的寫作'zipWith($)'。其工作原理完全相同; '''運算符只是一個縮小版本的'id'。 – leftaroundabout

+1

如果你「試圖分析」,你應該包括你試圖分析的細節,或者潛在的答覆者可能只是重新解釋你理解的內容,而完全錯過你不瞭解的內容。 – user2407038

回答

14

類型的zipWith是:

zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] 

id類型是:

id :: d -> d 

所以,如果我們現在要得出的zipWith id類型,我們推的id :: d -> d類型成第一個參數的類型爲zipWith

d -> d 
~ a -> (b -> c) 

這意味着:a ~ da ~ b -> c。所以這意味着zipWith id的類型現在是:

zipWith id :: [a] -> [b] -> [c] 
-> zipWith id :: [b -> c] -> [b] -> [c] 

這是如何工作:第一個列表必須包含的功能f :: b -> c列表,第二個列表,元素x :: b的列表,並由此計算元素列表f x :: c

例如:

Prelude> zipWith id [(+1),(5/),(3*),(3-)] [1,4,2,5] 
[2.0,1.25,6.0,-2.0] 

因爲1+12.05/41.253*26.03-5-2.0

所以zipWith id將採取兩個元素fx,以及對這些應用id f x,或更詳細的(id f) x。由於id ff,因此它將計算f x

因此我們可以得出結論,zipWith是一個元素映射。

+0

'〜'是什麼意思? –

+1

@zero_coding:表示[*類型相等*](https://stackoverflow.com/a/27667708/67579)。因此,例如'a〜d'意味着'a'和'd'是相同的類型。 [進一步閱讀](https://wiki.haskell.org/GHC/Type_families#Equality_constraints)。 –

+0

@zero_coding我已經添加了一個可以讓你理解'〜'的答案。只是簡單的類型推理邏輯。但是,@Willem Van Onsem的回答非常好。 – pamu

5

謝謝Willem Van Onsem給出了很好的答案。

讓我們從ghc的類型推斷系統的角度來理解zipWith id

第一,考慮的zipWithzipWith

Prelude> :info zipWith 
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] 
    -- Defined in ‘GHC.List’ 

第一自變量的類型是接受一個函數,它接受兩個參數的函數。

(a -> b -> c)也可以重新寫爲a -> (b -> c)

現在考慮zipWith idid的類型是從a -> a

我們已經把id放在一個必須使用兩個參數函數的地方。

因此,類型推理將使(a -> b -> c)樣子a -> (b -> c)(通知a -> (b -> c)需要一個arument和給b -> c即一個參數的功能。)

但是,使a -> (b -> c)標識功能將是可能的,只有a是( b - > c)。

a是(二 - > c)該函數a -> b -> c變爲((二 - > C) - >(B - > C))

所以,類型推斷系統將推斷a作爲(b -> c)並將所得輸出將是[a] -> [b] -> [c]替換ab -> c

用(b→c)代替a

使(a - > b - > c)看起來像id。 (a→b→c)可以看起來像id通過上述替換。 ((b→c)→b→c),其中x爲(b→c)→b→c),其中(b→c)→b→c) C)

zipWith :: ((b -> c) -> b -> c) -> [b -> c] -> [b] -> [c] 

所以最後我們得到的輸出[b -> c] -> [b] -> [c]

相關問題