首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对zipWith竞价的解释($)

对zipWith竞价的解释($)
EN

Stack Overflow用户
提问于 2013-11-21 19:51:00
回答 4查看 317关注 0票数 2

我一直在试图理解这段代码,但我无法清楚地结束它:

代码语言:javascript
复制
ghci > :t zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
ghci > :t ($)
($) :: (a -> b) -> a -> b
ghci > let c = zipWith ($)
ghci > :t c
c :: [b -> c] -> [b] -> [c]

[b -> c]是如何在上述类型的签名中产生的?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-11-21 20:06:42

为了让zipWith ($)打印出来,我们必须将zipWith的第一个参数的类型与($)的类型统一起来,我将把它们写在一起,并使用唯一的名称来使其更加清晰。

代码语言:javascript
复制
zipWith :: (a        -> b -> c) -> [a]     -> [b] -> [c]
($)     :: ((x -> y) -> x -> y)

因此,zipWith的类型是当且仅当我们可以假定a ~ (x -> y)b ~ xc ~ y。没有什么能阻止这种统一的成功,因此我们可以将这些名称替换为zipWith的类型。

代码语言:javascript
复制
zipWith :: ((x -> y) -> x -> y) -> [x -> y] -> [x] -> [y]
($)     :: ((x -> y) -> x -> y)

然后继续进行应用程序,因为现在一切都很好地匹配。

代码语言:javascript
复制
zipWith ($) :: [x -> y] -> [x] -> [y]

这相当于您看到的类型变量名的特定选择。

票数 6
EN

Stack Overflow用户

发布于 2013-11-21 20:00:59

只是上下文替代,没有魔法。看:

代码语言:javascript
复制
ghci > :t zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
ghci > :t ($)
($) :: (a' -> b') -> a' -> b'

现在考虑一下zipWith ($)。它有第一个参数固定的(a -> b -> c) -> [a] -> [b] -> [c]类型,因此我们应该将(a -> b -> c) (第一个arg的类型)与(a' -> b') -> a' -> b' ($的类型)匹配。因此,我们有a = (a' -> b')b = a'c = b'zipWith[a' -> b'] -> [a'] -> [b'] (第一个参数是固定的,所以他从类型中消失了),这正是使用不同名称的类型变量得到的结果。

另外,还可以考虑zipWith语义:使用拉链(第一个参数),然后将两个列表压缩在一起。如果您的拉链是函数应用程序($是函数应用程序,是的!)然后,在压缩两个列表时,只需使用第二个列表的相应元素调用第一个列表的元素。功能类型反映了这一点。

票数 2
EN

Stack Overflow用户

发布于 2013-11-21 20:02:33

类型签名中指定的实际字母是任意的,可以是任意的。您可以像编写($)类型一样轻松地编写

代码语言:javascript
复制
(x -> y) -> x -> y

它需要两个参数,一个接受单个参数的函数,以及一个传递给函数的值。

zipWith的第一个参数是一个带有两个参数(a -> b -> c)的函数。给定($)的定义,您选择a作为(x -> y),选择b作为x,然后选择cy,因此您可以得到zipWith ($)的类型

代码语言:javascript
复制
[x -> y] -> [x] -> [y]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20130559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档