我打了一下,用zipWith
和接觸之後:第二個參數如何成爲函數列表?
Prelude Control.Applicative> :t zipWith id
zipWith id :: [b -> c] -> [b] -> [c]
爲什麼編譯期待下一個參數的函數列表?
我試圖分析,但不能得出結論,爲什麼下一個參數必須是函數列表。
當我通過id
到zipWith
時,簽名是如何得到應用的?
我打了一下,用zipWith
和接觸之後:第二個參數如何成爲函數列表?
Prelude Control.Applicative> :t zipWith id
zipWith id :: [b -> c] -> [b] -> [c]
爲什麼編譯期待下一個參數的函數列表?
我試圖分析,但不能得出結論,爲什麼下一個參數必須是函數列表。
當我通過id
到zipWith
時,簽名是如何得到應用的?
類型的zipWith
是:
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
和id
類型是:
id :: d -> d
所以,如果我們現在要得出的zipWith id
類型,我們推的id :: d -> d
類型成第一個參數的類型爲zipWith
:
d -> d
~ a -> (b -> c)
這意味着:a ~ d
和a ~ 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+1
是2.0
,5/4
是1.25
,3*2
是6.0
和3-5
是-2.0
。
所以zipWith id
將採取兩個元素f
和x
,以及對這些應用id f x
,或更詳細的(id f) x
。由於id f
是f
,因此它將計算f x
。
因此我們可以得出結論,zipWith
是一個元素映射。
'〜'是什麼意思? –
@zero_coding:表示[*類型相等*](https://stackoverflow.com/a/27667708/67579)。因此,例如'a〜d'意味着'a'和'd'是相同的類型。 [進一步閱讀](https://wiki.haskell.org/GHC/Type_families#Equality_constraints)。 –
@zero_coding我已經添加了一個可以讓你理解'〜'的答案。只是簡單的類型推理邏輯。但是,@Willem Van Onsem的回答非常好。 – pamu
謝謝Willem Van Onsem給出了很好的答案。
讓我們從ghc的類型推斷系統的角度來理解
zipWith id
。
第一,考慮的zipWith
zipWith
Prelude> :info zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
-- Defined in ‘GHC.List’
第一自變量的類型是接受一個函數,它接受兩個參數的函數。
(a -> b -> c)
也可以重新寫爲a -> (b -> c)
現在考慮zipWith id
。 id
的類型是從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]
替換a
與b -> 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]
值得關注的是,這是更常見的寫作'zipWith($)'。其工作原理完全相同; '''運算符只是一個縮小版本的'id'。 – leftaroundabout
如果你「試圖分析」,你應該包括你試圖分析的細節,或者潛在的答覆者可能只是重新解釋你理解的內容,而完全錯過你不瞭解的內容。 – user2407038