[英]Need help in understanding the function application operator in haskell
这是一段代码
map ($ 3) [(4+), (10*), (^2), sqrt]
给出输出
[7.0,30.0,9.0,1.7320508075688772]
我知道$具有最低优先级,因此$右边的表达式一起评估。 但我不明白的是($ 3)如何表现为一个函数(因为Map将函数和列表作为参数)。 我不明白为什么列表中的每个函数都应用于3。
请记住($)
实际上是一个函数:
($) :: (a -> b) -> a -> b
f $ x = f x
($ 3)
是\\f -> (f $ 3)
简写。 它的类型? 好:
3 :: Double -- for sake of simplicity
($) :: (a -> b) -> a -> b
($ 3) :: (Double -> b) -> b
所以($ 3)
是一个函数,它将函数从Double
为某个函数并将该函数应用于3
。 现在,如果我们使用map
,我们最终得到:
map ($ 3) [(4+), (10*), (^2), sqrt]
= [($ 3) (4+), ($ 3) (10*), ($ 3)(^2), ($ 3) sqrt]
= [(4+) $ 3, (10*) $ 3, (^2) $ 3, sqrt $ 3]
= [4 + 3, 10 * 3, 3 ^ 2, sqrt 3]
= [7, 30, 9, sqrt 3]
我们先来看一下($)
的类型签名:
ghci>> :t ($)
($) :: (a -> b) -> a -> b
和定义:
($) f x = f x
要么:
f $ x = f x
在上面,我们有一个部分 ,我们创建了一个部分应用的($)
版本,第二个参数(类型为a
)设置为3
。 现在,我们知道3
类型为Num a => a
,因此我们的部分应用程序的类型签名必须是Num a => (a -> b) -> b
。
接下来,让我们看一下列表中的每个函数,每个函数都是($ 3)的参数。 正如预期的那样,它们是函数,事实证明它们的类型Num a -> a -> a
实际上比所需的更受约束(所以我们很好)。 为了清楚起见,我们可以看看一个应用程序会带来什么:
($3) (4+)
我们可以在没有以下部分的情况下重写:
($) (4+) 3
从上面的函数定义中可以清楚地了解应用程序的进展情况。
最后一个令人困惑的部分可能是关于列表的类型($3) (4+)
评估为7
,而不是repl中的7.0
。 如果我们记得列表是同类的并且注意到列表中的一个函数sqrt
接受并返回浮点值,我们会看到对所有应用程序强制执行此类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.