为什么在没有括号的情况下,haskell中的负数不可能相乘
在haskell gchi中乘以为什么在没有括号的情况下,haskell中的负数不可能相乘,haskell,syntax,Haskell,Syntax,在haskell gchi中乘以5*-3会给出错误和错误。但是相乘5*(-3)可以正常工作。为什么需要括号 $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linki
5*-3
会给出错误和错误。但是相乘5*(-3)
可以正常工作。为什么需要括号
$ ghci
GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> 5 * -3
<interactive>:2:1:
Precedence parsing error
cannot mix `*' [infixl 7] and prefix `-' [infixl 6] in the same infix expression
Prelude> 5 * (-3)
-15
Prelude>
$ghci
GHCi,7.4.1版:http://www.haskell.org/ghc/ :? 求救
正在加载程序包ghc prim。。。链接。。。完成。
正在加载包整型gmp。。。链接。。。完成。
正在加载包库。。。链接。。。完成。
序曲>5*-3
:2:1:
优先解析错误
不能在同一中缀表达式中混合使用“*”[infixl 7]和前缀“-”[infixl 6]
序曲>5*(-3)
-15
序曲>
因为在Haskell中如何指定运算符。不幸的是,这有点神奇。这是语言规范中的一个奇怪的角落
一元减号是语言中唯一的一元运算符。对一元减号语法的支持只是为了支持negate
函数的语法糖
一方面,这使我们可以使-7
与-7
相同。另一方面,它破坏了其他东西,比如节语法
正如您所看到的,在编写混合固定表达式时,这会造成混乱
您需要将否定的用法括起来,如下所示:
5 * (-3)
因为-3不像其他语言那样是负数。
它是一元函数,后跟Num 3。规则是不能在二元运算符附近使用
-
运算符(Haskell唯一的一元运算符)
因为可以在Haskell中定义新的运算符,所以使用此规则的原因是,否则可能会引入潜在的解析歧义。假设您没有使用任何空格,并且指定了5*-3
这是否意味着
5*-3
或5*-3
?其他答案告诉你-
在Haskell中是一个非常特殊的运算符,具有奇怪的语法行为。我不认为这真的回答了你的问题,因为没有任何东西可以阻止语言设计师让5*-3
按照你期望的方式工作,即使有其他奇怪之处
因此,真正的答案是,他们根本不允许这样做
至于原因,我的猜测是因为它们的灵感不是来自类C语言的语法(如果你看Haskell语法的其余部分,确实很明显),而是来自更接近数学约定的符号,在数学中,通常需要在该位置插入一个
-3
。虽然这有点像是一个copout,因为数学通常也不使用任何东西来代替*
但经验法则是,当括号前面有函数应用程序或更高优先级的运算符时,将负数放在括号之间。到目前为止,这个问题对我一直有效。因为还没有公认的答案,我对这个有趣的问题做了一些研究,因为我发现在另一个地方也没有答案
简短的回答是:语法不允许这样做。
让我再解释一点数据,但首先让我们记住:
在haskell上,运算符是
现在,让我们看看错误消息:
Precedence parsing error
cannot mix `*' [infixl 7] and prefix `-' [infixl 6] in the same infix expression
这意味着什么?那么,我们应该开始定义什么是infixl7
和infixl6
。在他们的语法上,他们有这样的东西:
infixr 9 .
infixr 8 ^, ^^, **
infixl 7 *, /, `quot`, `rem`, `div`, `mod`
infixl 6 +, -
infixr 5 :
infix 4 ==, /=, <, <=, >=, >
infixr 3 &&
infixr 2 ||
infixl 1 >>, >>=
infixr 1 =<<
infixr 0 $, $!, `seq`
Prelude> 5 * +3
您将得到以下错误:
parse error on input `+'
等等,如果这是sintax错误,为什么错误消息不同
好的,一元“-”运算符在haskell中似乎非常特殊(正如其他答案所说),并且被用于语法的其他部分,因此,理论上这将转到语法树的另一个分支,并在其他地方抛出错误
如果您想了解更多有关一元“-”运算符的信息,可以。这是一个合理的猜测,但实际上并非如此。您可以对优先级低于加法和减法的运算符使用-
:5==-3
正常工作。但它确实需要间隔,就像所有连接为有效词汇标记的标记一样。只是Haskell(可能是出于设计)有相对较少的两个类似运算符的令牌自然顺序排列的情况,但也可能发生,例如另一个例子是->
和\
中的\x->\y->x+y
。实际上,(
是一个二进制运算符,而不是一元运算符。一元否定函数被称为否定
(因为在其他答案中讨论了歧义)<代码>-3
是Haskell中的数字文字,而不是函数调用。