为什么`-`(减号)不适用于操作员部分?

时间:2015-03-04 15:22:58

标签: haskell

根据位置,Haskell中的部分应用程序得到了正确的答案。

Prelude> (/2) 10
5.0
Prelude> (2/) 10
0.2
Prelude> (+3) 10
13
Prelude> (3+) 10
13

然而,对于 - 运算符,我得到(-3)的错误,因为Haskell(似乎)将其解释为值-3而非部分应用。

Prelude> (-3) 10

<interactive>:4:1:
    Could not deduce (Num (a0 -> t))
      arising from the ambiguity check for ‘it’
    from the context (Num (a -> t), Num a)
      bound by the inferred type for ‘it’: (Num (a -> t), Num a) => t
      at <interactive>:4:1-7
    The type variable ‘a0’ is ambiguous
    When checking that ‘it’
      has the inferred type ‘forall a t. (Num (a -> t), Num a) => t’
    Probable cause: the inferred type is ambiguous

如何在此示例中解决此问题以获取7

1 个答案:

答案 0 :(得分:21)

使用subtract-是Haskell中唯一的运算符,它出现在前缀二进制中缀变体中:

let a = -3     -- prefix  variant
let b = (-3)   -- also prefix variant!
let c = 4 - 3  -- binary variant

因此,您必须使用(subtract 3) 10。另见section 3.4 in the Haskell 2010 report(强调我的):

  

特殊形式-e表示前缀否定,Haskell中唯一前缀运算符,是negate (e)的语法。二元-运算符不一定引用Prelude中-的定义;它可能会被模块系统反弹。但是,一元-将始终引用Prelude中定义的negate函数。 -运算符的本地含义与一元否定之间没有联系。

     

前缀否定与Prelude中定义的中缀运算符-具有相同的优先级(参见表4.1)。因为e1-e2解析为二元运算符-的中缀应用程序,所以必须为替代解析编写e1(-e2)。同样,(-)(\ x y -> x-y)的语法,与任何中缀运算符一样,并且不表示(\ x -> -x) - 必须使用negate-

section 3.5总结(再次强调我的):

  

因为(- exp)在语法中被特别处理,subtract不是一个部分,而是前缀否定的应用,如上一节所述。但是, Prelude 中定义了(subtract exp)函数,因此(+ (- exp))等同于不允许的部分。表达式{{1}}可以用于相同的目的。