Haskell如何知道哪个函数可以先运行?

时间:2013-02-08 11:57:08

标签: haskell infix-notation

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

这是怎么回事。

说我们有以下一行

a . b

在Haskell。 显然,我们正在组成两个函数,a和b。但是如果函数a将另外两个函数作为参数怎么办呢。是什么阻止了它的运作。和b?您可以将它括在括号中,但这不应该有所区别,因为表达式仍然计算为函数,前缀1,前缀函数优先于中缀函数。

如果你这样做

(+) 2 3 * 5
例如,它将输出25而不是17。

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

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

a . b

as“apply。和b to the function a” 并将其解释为“撰写函数a和b”。

4 个答案:

答案 0 :(得分:11)

如果你没有把一个parens放在一个操作符周围,它的总是解析为infix;即作为操作员,而不是操作员 例如。如果你有f g ? i j?周围没有任何问题,那么整个事情就是调用(?)(解析为(f g) ? (i j),相当于(?) (f g) (i j)

答案 1 :(得分:4)

我认为你所寻找的是固定性声明(见The Haskell Report)。

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

例如,有

infixl 7 *
infixl 6 +

表示+*都是左关联中缀运算符。 *优先7,而+优先6,即*强于+。 在报告页面中,您还可以看到.定义为infixr 9 .

答案 2 :(得分:3)

  

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

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

f . g

f,g和(。)是函数,或者其他什么。

反过来说:

  1. Parser看到f . g(或者,语法上等同于:i + j
  2. 按照词汇和语法规则将其作为App (App (.) f) g之类。
  3. 只有这样,当类型检查员看到App a b时才会断定a必须是一个函数。

答案 3 :(得分:1)

(+) 2 3 * 5

被解析为

((+) 2 3) * 5

因此

(2 + 3) * 5

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