我打了一下,用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