2

我正在编写一种具有一些功能元素的自定义语言。当我卡在某个地方时,我通常会检查 Haskell 是如何做到的。不过,这一次,我想给 Haskell 举个例子,这个问题有点复杂。

事情是这样的。

假设我们有以下行

a . b

在哈斯克尔。显然,我们正在组合两个函数,a 和 b。但是如果函数 a 将另外两个函数作为参数呢?是什么阻止它在 . 和乙?您可以将它括在方括号中,但这不应该有什么不同,因为表达式仍然计算为一个函数,一个前缀一,并且前缀函数优先于中缀函数。

如果你这样做

(+) 2 3 * 5

例如,它将输出 25 而不是 17。

基本上我要问的是,当您希望中缀函数在前面的前缀函数之前运行时,Haskell 使用什么机制。

所以。如果“a”是一个以两个函数作为参数的函数。你如何阻止 Haskell 解释

a . b

作为“将 . 和 b 应用于函数 a”并将其解释为“组合函数 a 和 b”。

4

4 回答 4

11

如果你不在运算符周围加上括号,它总是被解析为中缀;即作为运算符,而不是操作数。
例如,如果你有f g ? i j,周围没有括号?,所以整个事情都是对(?)(解析为(f g) ? (i j),相当于(?) (f g) (i j))的调用。

于 2013-02-08T12:28:55.410 回答
4

我认为您正在寻找的是固定性声明(请参阅The Haskell Report)。

它们基本上允许您声明中缀函数的运算符优先级。

例如,有

infixl 7 *
infixl 6 +

这意味着+*都是左结合中缀运算符。 *优先级为 7,而+优先级为 6,即*绑定比+. 在报告页面中,您还可以看到.定义为infixr 9 .

于 2013-02-08T12:33:14.553 回答
3

基本上我要问的是,当您希望中缀函数在前面的前缀函数之前运行时,Haskell 使用什么机制。

只是指出一个误解:这纯粹是表达式如何解析的问题。Haskell 编译器不知道(或:不需要知道)是否,在

f . g

f、g 和 (.) 是函数,或者其他。

它反过来:

  1. 解析器看到f . g (或者,语法上等价的i + j:)
  2. 将其视为App (App (.) f) g遵循词汇和语法规则之类的东西。
  3. 只有这样,当类型检查器看到App a b它的结论时,它a必须是一个函数。
于 2013-02-08T13:51:41.517 回答
1
(+) 2 3 * 5

被解析为

((+) 2 3) * 5

因此

(2 + 3) * 5

也就是说,因为函数应用程序(如(+) 2 3)首先被评估,在中缀表示法中的函数之前,如*.

于 2013-02-08T12:09:40.350 回答