运算符(例如+)的行为是否更像咖喱函数或带有成对元组类型参数的函数?

Tim*_*Tim 1 haskell language-lawyer

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

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

  • 咖喱函数,或
  • 一个参数具有成对元组类型的函数?

用话务员的话说#,我#不是那样(#)(#)是咖喱函数,并且如果#表现得像咖喱函数,我猜没有必要了(#),不是吗?

谢谢。

Bar*_*icz 6

根据Haskell 2010报告:

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

因此,+是一个标识符。标识符可以标识不同的事物,对于+,它可以标识Num类型类中的函数。该函数的行为类似于任何其他Haskell函数,但涉及该函数的表达式的不同解析规则除外。

具体来说,在3.2中进行了描述。

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

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

运算符可以是运算符,例如+$$,或者是用重音符(反引号)引起的普通标识符,例如`op`2


因此,总结一下:

+是一个标识符。这是一个运算符,因为它不是以冒号开头,并且仅使用非字母数字字符。当用于表达式(作为表达式的一部分)时,我们将其视为运算符,这又意味着它是一个函数。

具体来说,要回答您的问题,您所说的一切仅涉及语法。()in表达式的需要仅是启用前缀应用程序。在没有其他必要消除歧义的所有其他情况下(例如:type),通过这种方式可能更容易实现,因为这样您就可以期待普通标识符并为您提供一个繁琐的负担。


1就其价值而言,我认为该报告实际上在这里具有误导性。此特定声明似乎与其他部分冲突,关键是:

双重地,运算符可以通过将其括在括号中而转换为普通标识符。

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


2我想在这里指出另外一件事。无论是`(+)`(`add`)的确需要解析。第二个是可以理解的,因为该报告特别指出,将括号括起来仅适用于运算符标识符,因此可以看到`add`,虽然是运算符,却不是像那样的运算符标识符+

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

  • 也许我们可以说,“ +”是*语法*的运算符,这意味着*表示*函数。为了引用“ +” *功能*,语法规则规定我们必须将“ +”符号括在括号中,例如:((+)`)。所以是的,它只是语法,而且`GHCi>:i +`*工作*-没有括号。`:t`需要一个可键入的实体,但是`:i`需要一个标识符(或其他东西)。 (2认同)

dup*_*ode 6

(+)+引用相同的东西,一个type的函数Num a => a -> a -> a(+)当我们要使用它的前缀,以及+我们要写它的前缀时,我们将其拼写为。没有本质区别;这只是语法问题

因此+(无节)的行为就像需要一对参数的函数一样(因为部分应用程序需要节)。()就像咖喱。

尽管从语法角度来看这不是不合理的,但我不会这样描述。Haskell中的非咖喱函数将元组作为参数(例如(a, a) -> a与相对a -> a -> a),并且这里没有实际的元组。2 + 3最好将其视为的缩写(+) 2 3,关键是两种情况下使用的功能都相同。

  • @Tim对我来说,pair参数是`(a,b)`,而接受pair的函数是`(a,b)-> c`。不管您将其应用为前缀还是前缀,“ +”的类型都是“ a-> a-> b”,因此可以使用。 (3认同)
  • @Tim现在,我明白了您要达到的目标。尽管以某种方式看待它很有道理,但我不会这样描述,因为在“ 2 + 3”中,任何地方都没有实际的对。最好将`2 + 3`视为`(+)2 3`的缩写。 (2认同)