首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell元算子和infix算子

Haskell元算子和infix算子
EN

Stack Overflow用户
提问于 2021-01-07 20:17:26
回答 2查看 289关注 0票数 2

我有两段Haskell代码。

这个很好用:

代码语言:javascript
复制
(3+) $ 5

这个错误引发了一个错误:

代码语言:javascript
复制
3+ $ 5

为什么会发生这种事?由于+相对于$的优先级更高,它们的解析不都是相同的吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-08 16:37:48

简短回答:表达式(3+)是“节”的一个例子。它与通常的infix运算符语法(如2+3)或通常的函数应用程序(如sqrt 16)在语法上是不同的,而包围括号并不是通常用于排序操作的分组括号。相反,这一节中的括号是语法的一部分,如果没有括号,您就不能编写一个部分,就像您不能编写没有括号的元组(1,2)一样。

很长的答案:

Haskell中有三个不同的函数调用表达式语法:

  1. 通常的函数应用程序通过并置,其中表示函数的表达式与表示参数的表达式相邻(即并列),如在f x中。在本例中,fx都是由单个标识符组成的表达式。不需要括号,但可以在不影响意义((f) (((x))))的情况下添加括号,对于更复杂的表达式,可能需要使用括号才能使操作顺序正确。但是,这些是“分组括号”,是用于命令操作的表达式语法的一部分,它们与并置语法itself.
  2. Infix操作符分离,在两个参数之间放置一个二进制运算符,如在x / y中,运算符/表示的函数被应用于参数x,该应用程序的结果应用于参数y。同样,可以将括号添加到两个表达式参数或整个结果表达式:((x) / (y))周围。在更复杂的表达式中,它们可能需要正确的操作顺序。然而,这些都是“分组括号”,这是表达式本身语法的一部分,而不是infix运算符语法的一部分。
  3. A节分为两种类型:右节(/ 2)和左段(2 /),它们由一个infix运算符和一个放在彼此旁边的表达式组成,按括号之间的顺序排列(操作符第一或运算符最后)。注意,括号是语法的的一部分。节不能不带括号写,就像元组不能没有括号写一样。一个部分创建了一个部分应用的函数:(2 /)将操作符/应用于2,就像它出现在一个更常见的infix表达式的左侧一样。结果是一个函数需要多一个参数(丢失的右侧)。因此,(2 /) 3 == 2 / 3.类似地,节(/ 2)将运算符/应用于2,就像2出现在infix表达式的右侧一样。结果是一个函数,期望丢失的左侧.因此,(/ 2) 3 == 3 / 2.为了清楚起见,这是将==左侧的一个节和一个数字与右边的infix运算符语法并列。

对于一段语法在分组括号(即,括号不是语法的一部分)与节(即语法的括号部分)之间是否并置,从来没有任何含糊之处。尽管表达式(f x)(+ x)看起来很相似,但fx是表达式,而+是运算符。因为+是运算符而不是表达式,所以(+ x)必须是节。同样,由于fx都是表达式而不是运算符,所以必须将(f x)放在分组括号内。

还有一个更复杂的问题。运算符+可以通过将其放在括号内(如(+) )来转换为独立的表达式。同样,括号是语法的的一部分。与节(2 +)(+ 2)将运算符转换为函数表达式(在本例中为一个变量的函数)一样,语法(+)将运算符转换为表示与运算符关联的两个参数函数的函数表达式。与节一样,不可能将(+) (语法的括号部分)与(15) (分组括号)混淆,因为+是运算符,而15是表达式。

因此,以下是应用两个操作符+$的等效方法

代码语言:javascript
复制
(3+) $ 5   -- infix operator $ applied to section (3+) and 5
((3)+) $ 5 -- add optional grouping parentheses to expression part of section
($5) (3+)  -- juxtaposition of section ($5) and (3+)
((3+)$) 5  -- juxtaposition of section ((3+)$) with 5; here, the section ((3+)$) itself
           -- consists of a section expression (3+) and the operator $.
           -- both sets of parentheses are part of the section syntax and must be present
((+)3) $ 5 -- infix $ applied to juxtaposition of (+) 3 and 5:  the parentheses in (+) are
           -- part of the syntax, the outer parentheses in ((+)3) are grouping parentheses
(+)3 $ 5   -- because of order of operations (juxtaposition before infix),
           -- those grouping parentheses are optional

相反,没有有效的语法结构允许两个二进制运算符在不插入括号的情况下出现在彼此旁边,这就是为什么以下语法无效的原因:

代码语言:javascript
复制
3+ $ 5

额外的琐事#1:表达式3+$5是有效的语法,但这是因为+$被认为是一个新的多字符运算符,比如++>>=

额外的琐事2:有一种情况是,两个操作符可以放在一起。二进制运算符可以放置在一元否定运算符-旁边,条件是二进制运算符的优先级较低(比二进制运算符-的通常优先级低,因此低于优先级6)。

代码语言:javascript
复制
-5 == -5
   ^^^^  these two operators can appear next to each other, because == is
         precedence level 4
-5 + -3
   ^^^   precedence parsing error because + is level 6
票数 2
EN

Stack Overflow用户

发布于 2021-01-07 20:56:08

+$是infix操作符,您不能在左边直接给+一个参数来修饰它--您需要将其放在括号中,如(3+)(+3)(+),以使其成为一个可与$一起使用的函数。第二段代码在语法上是无效的,因为不能将+视为后缀操作符,尽管可以在括号内部分应用它。

如果$是一个函数f,那么它将被解析为3 + (f 5),但是无法解析彼此相邻的两个运算符。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65619339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档