[英]Trying to understand function application operator in Haskell
I'm trying to wrap my head around the function application operator ( $
) in Haskell. 我试图在Haskell中围绕函数应用程序运算符( $
)。
I'm working through the examples in Learn You a Haskell, and I thought I understood the following example: 我正在研究Learn You a Haskell中的示例,我认为我理解了以下示例:
Prelude> map ($ 3) [(+4), (*10), (^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772]
I then tried the following variant, which also worked fine: 然后我尝试了以下变体,它也运行良好:
Prelude> map ($ 3) [(+4), (*10), (\x -> x^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772]
Finally, I tried modifying the third function in the list as follows, which generates an error: 最后,我尝试按如下方式修改列表中的第三个函数,这会生成错误:
Prelude> map ($ 3) [(+4), (*10), (\x -> 2^x), sqrt]
<interactive>:53:38:
Ambiguous type variable `b0' in the constraints:
(Floating b0)
arising from a use of `sqrt' at <interactive>:53:38-41
(Integral b0) arising from a use of `^' at <interactive>:53:33
(Num b0) arising from the literal `3' at <interactive>:53:8
Probable fix: add a type signature that fixes these type variable(s)
In the expression: sqrt
In the second argument of `map', namely
`[(+ 4), (* 10), (\ x -> 2 ^ x), sqrt]'
In the expression: map ($ 3) [(+ 4), (* 10), (\ x -> 2 ^ x), sqrt]
Prelude>
It seems if the final sqrt
function is somehow begin associated with the previous list element, as the following variant works ok: 似乎最终的sqrt
函数以某种方式开始与前一个list元素相关联,因为以下变体可以正常工作:
Prelude> map ($ 3) [(+4), (*10), (\x -> 2^x)]
[7,30,8]
Can someone enlighten me as to what's going on here? 有人可以告诉我这里发生了什么吗?
The type of the used exponentiation operator is 使用的取幂运算符的类型是
(^) :: (Num a, Integral b) => a -> b -> a
so when you use \\x -> 2^x
, you get an Integral
constraint for the 3
. 所以,当你使用\\x -> 2^x
,你会得到一个Integral
的限制3
。 But sqrt
imposes a Floating
constraint. 但是sqrt
强加了一个Floating
约束。 So the type of the 3 must satisfy 所以3的类型必须满足
3 :: (Integral t, Floating t) => t
but there is no instance for both among the default type list, which is Integer
and Double
, so the defaulting fails, and you're left with an ambiguous type variable. 但是默认类型列表中没有两个实例,它们是Integer
和Double
,因此默认失败,并且你留下了一个模糊的类型变量。
When you had \\x -> x^2
, there was only a Num
constraint from the first functions, and Floating
from sqrt
, so the type was defaulted to Double
. 当你有\\x -> x^2
,第一个函数只有一个Num
约束,而从sqrt
Floating
,所以类型默认为Double
。
You can make it work if you use 如果使用,可以使它工作
(**) :: Floating a => a -> a -> a
as your exponentiation operator, then the type can again be defaulted to Double
. 作为你的指数运算符,那么类型可以再次默认为Double
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.