haskell - 试图理解 Haskell 中的函数应用运算符

标签 haskell operators

我正试图围绕 Haskell 中的函数应用程序运算符 ( $ )。

我正在研究 Learn You a Haskell 中的示例,并且我认为我理解了以下示例:

Prelude> map ($ 3) [(+4), (*10), (^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772] 

然后我尝试了以下变体,它也运行良好:
Prelude> map ($ 3) [(+4), (*10), (\x -> x^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772]

最后,我尝试如下修改列表中的第三个函数,结果报错:
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> 

好像最后的sqrt函数以某种方式开始与前一个列表元素相关联,因为以下变体可以正常工作:
Prelude> map ($ 3) [(+4), (*10), (\x -> 2^x)]
[7,30,8]

有人可以告诉我这里发生了什么吗?

最佳答案

使用的幂运算符的类型是

(^) :: (Num a, Integral b) => a -> b -> a

所以当你使用 \x -> 2^x , 你会得到一个 Integral 3 的约束.但是sqrt强加一个 Floating约束。所以 3 的类型必须满足
3 :: (Integral t, Floating t) => t

但是默认类型列表中没有这两个实例,即 IntegerDouble ,所以默认失败,你留下一个模棱两可的类型变量。

当你有 \x -> x^2 , 只有一个 Num来自第一个函数的约束和 Floating来自 sqrt ,所以类型默认为 Double .

如果你使用,你可以让它工作
(**) :: Floating a => a -> a -> a

作为您的指数运算符,那么类型可以再次默认为 Double .

关于haskell - 试图理解 Haskell 中的函数应用运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15362990/

相关文章:

sorting - 为什么 sortBy 不采用 (a -> a -> Bool)?

haskell - 无法将预期类型 Int 与 Haskell 中的实际类型 Int -> Int 匹配

haskell - 在 haskell 中使用泛型列出构造函数名称

c - C 中的后缀增量和前缀运算符

ruby - 一元问号 (?) 运算符的作用是什么?

c - "The only operator that gives back a value is the de-referencing operator"

loops - 遍历 Haskell 中的两个变量

haskell - 如何在列表推导中有多个无限范围?

c++ - 重载赋值运算符,rhs是函数调用

operators - 为什么 Io REPL 和解释器给我两个不同的值?