Tim*_*Tim 1 haskell language-lawyer
如何找出运算符“ +”的类型?说运算符+不是函数。
诸如此类的运算符的+ 行为更像是什么,
用话务员的话说#,我#不是那样(#)。(#)是咖喱函数,并且如果#表现得像咖喱函数,我猜没有必要了(#),不是吗?
谢谢。
根据Haskell 2010报告:
运算符[不是以冒号开头]是普通标识符。1个
因此,+是一个标识符。标识符可以标识不同的事物,对于+,它可以标识Num类型类中的函数。该函数的行为类似于任何其他Haskell函数,但涉及该函数的表达式的不同解析规则除外。
具体来说,在3.2中进行了描述。
运算符是可以使用中缀语法(第3.4节)或部分使用(第3.5节)应用的函数。
为了确定什么构成运算符,我们可以进一步阅读:
运算符可以是运算符,例如
+或$$,或者是用重音符(反引号)引起的普通标识符,例如`op`2。
因此,总结一下:
+是一个标识符。这是一个运算符,因为它不是以冒号开头,并且仅使用非字母数字字符。当用于表达式(作为表达式的一部分)时,我们将其视为运算符,这又意味着它是一个函数。
具体来说,要回答您的问题,您所说的一切仅涉及语法。()in表达式的需要仅是启用前缀应用程序。在没有其他必要消除歧义的所有其他情况下(例如:type),通过这种方式可能更容易实现,因为这样您就可以期待普通标识符并为您提供一个繁琐的负担。
1就其价值而言,我认为该报告实际上在这里具有误导性。此特定声明似乎与其他部分冲突,关键是:
双重地,运算符可以通过将其括在括号中而转换为普通标识符。
我的理解是,在第一个引号中,“普通”的上下文表示它不是类型构造函数运算符,而是值类别运算符,因此“值类别”表示“普通”。在其他引号中,“普通”用于不是操作员标识符的标识符;区别显然是应用程序。这将证实以下事实:将运算符标识括在括号中,出于前缀应用的目的,我们将其转换为普通标识。ew,至少我没有写报告;)
2我想在这里指出另外一件事。无论是`(+)`也(`add`)的确需要解析。第二个是可以理解的,因为该报告特别指出,将括号括起来仅适用于运算符标识符,因此可以看到`add`,虽然是运算符,却不是像那样的运算符标识符+。
第一种情况实际上对我来说比较棘手。由于我们可以通过将普通标识符括在反引号中来获得运算符,因此(+)它与并不完全一样add。这种语言,或者至少是我测试过的GHC解析器,似乎在“普通普通”标识符和通过用括号括起来的普通标识符之间进行区分。目前,这是否真的与规范相抵触还是混合命名的另一种情况?
(+)并+引用相同的东西,一个type的函数Num a => a -> a -> a。(+)当我们要使用它的前缀,以及+我们要写它的前缀时,我们将其拼写为。没有本质区别;这只是语法问题。
因此
+(无节)的行为就像需要一对参数的函数一样(因为部分应用程序需要节)。()就像咖喱。
尽管从语法角度来看这不是不合理的,但我不会这样描述。Haskell中的非咖喱函数将元组作为参数(例如(a, a) -> a与相对a -> a -> a),并且这里没有实际的元组。2 + 3最好将其视为的缩写(+) 2 3,关键是两种情况下使用的功能都相同。