在ghci中,当我键入时
:t (-)
为了计算(-)
的类型,它返回
(-) :: Num a => a -> a -> a
然而,当我编写-1
时,haskell返回一个数字,这似乎意味着(-)
的类型是Num a => a -> a
。(-)
怎么可能看起来有两种不同的类型?
这是该语言中的一个设计决策。-1
是一个数字,但它在上下文中的用法与函数(-)
无关。(正如Ackdari在回答中提到的,这种用法与函数negate
有关。(有几个折衷方案可以使其发挥作用:
-
不能对
(-)
运算符进行右切片。作为一种变通方法,Haskell提供了subtract
函数。 -
除非负整数在赋值的开头(例如直接在
=
或->
之后(,否则不能写没有括号的负整数。这会产生一个解析错误:let x = 8 * -1
相反,它应该写为
let x = 8 * (-1)
然而,这很好:
let x = -1 * 8
这些被认为是语言设计者的合理权衡。
答案已经在haskell wiki中描述,它声明
一元减号是前奏函数
negate
的语法糖
因此函数(-)
始终是a - b
函数,如果您编写以下代码CCD_ 16编译器将其翻译为CCD_。
一元减号在Haskell中很特殊。如报告第3.4节所述:
特殊形式
-e
表示前缀否定,是Haskell中唯一的前缀运算符,是negate(e)
的语法。二进制CCD_ 20运算符不一定引用前奏曲中CCD_ 21的定义;它可能被模块系统反弹。然而,一元-
将始终引用前奏曲中定义的negate
函数。-
算子的局部意义与一元否定之间没有联系。