首页 > 解决方案 > 运算符(例如 +)的行为更像是 curried 函数还是带有一对元组类型参数的函数?

问题描述

如何找出运算符“+”的类型?说运算符+不是函数。

诸如此类的运算符的+ 行为更像是,

按运营商的说法#,我的意思#不是(#)(#)是一个柯里化函数,如果#表现得像一个柯里化函数,我想没有必要拥有(#),不是吗?

谢谢。

标签: haskelllanguage-lawyer

解决方案


根据 Haskell 2010 年的报告:

运算符符号 [不以冒号开头] 是一个普通标识符。1

因此,+是一个标识符。标识符可以识别不同的事物,在 的情况下+,它从类型类中识别出一个函数Num。该函数的行为类似于任何其他 Haskell 函数,除了涉及所述函数的表达式的不同解析规则。

具体来说,这在3.2中有所描述。

运算符是一个函数,可以使用中缀语法(第 3.4 节)应用,或使用节部分应用(第 3.5 节)。

为了确定什么构成运算符,我们可以进一步阅读:

运算符要么是运算符符号,例如+or $$,要么是包含在重音符号(反引号)中的普通标识符,例如`op`2


所以,总结一下:

+是一个标识符。它是一个操作符符号,因为它不以冒号开头,并且只使用非字母数字字符。当在表达式中使用时(作为表达式的一部分进行解析),我们将其视为operator,这反过来意味着它是一个函数。

为了具体回答您的问题,您所说的一切都只涉及语法。对()in 表达式的需求仅仅是启用前缀应用程序。在所有其他不需要这种消歧的情况下(例如:type),以这种方式实现可能更容易,因为您可以只期望普通标识符并将负担推给用户。


1对于它的价值,我认为该报告在这里实际上具有误导性。这个特定的陈述似乎与其他部分相冲突,关键是:

对偶,运算符符号可以通过将其括在括号中转换为普通标识符。

我的理解是,在第一个引号中,“普通”的上下文意味着它不是类型构造函数运算符,而是值类别运算符,因此“值类别”表示“普通”。在其他引号中,“普通”用于不是操作符标识符的标识符;区别显然是应用程序。这将证实将运算符标识符包含在括号中的事实,我们将其转换为普通标识符以用于前缀 application。呼,至少我没有写那份报告;)


2我想在这里指出一件额外的事情。既不`(+)`也不(`add`)实际解析。第二个是可以理解的,因为报告明确指出,用括号括起来仅适用于操作符标识符,可以看出`add`,虽然是操作符,但不是像 . 那样的操作符标识符+

第一种情况对我来说实际上有点棘手。由于我们可以通过将普通标识符括在反引号中来获得运算符,(+)因此并不完全像add. 我测试过的语言,或者至少是 GHC 解析器,似乎区分了“普通普通”标识符和通过用括号括起来运算符符号获得的普通标识符。这是否实际上与规范相矛盾,或者是另一种混合命名的情况,目前我还不知道。


推荐阅读