Multiplying 5 * -3
in haskell gchi gives me and error. But multiplying 5 * (-3)
works ok. Why are the brackets needed?
$ 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>
Negative literals. Enable negative numeric literals. The literal -123 is, according to Haskell98 and Haskell 2010, two tokens, a unary minus ( - ) and the number 123, and is desugared as negate (fromInteger 123) .
Using a Number Line to Add Integers Look Out: sometimes you may see parentheses around negative numbers. These do not mean that we need to multiply; they're just used so that we don't confuse negatives with subtraction.
The negative sign tells you how far away the number is from the zero. So -3 means you are 3 steps away from 0 and -5 means you are 5 steps away from zero. Therefore, -5 is smaller than -3 because you are further away from zero.
Because of how the unary minus operator is specified in Haskell. It is a bit magic, unfortunately. It's an odd corner of the language specification.
Unary minus is the only unary operator in the language. Support for unary minus syntax is simply to support syntactic sugar for the negate
function.
On the one hand, this lets us make - 7
the same as -7
. On the other hand, it breaks other things, like section syntax.
And as you see, it makes for confusion when writing mix fixed expressions.
You need to parenthesize the use of negate, as follows:
5 * (-3)
Since there is still no accepted answer I did a little of research about this interesting question because I found it unanswered on another place too.
Short answer is: the grammar doesn't allow it.
Let me explain that a little bit more datailed, but first let's remember this:
On haskell, operators are functions on infix notation.
Now, let's see the error message:
Precedence parsing error
cannot mix `*' [infixl 7] and prefix `-' [infixl 6] in the same infix expression
What does that means? Well, we should start defining what infixl 7
and infixl 6
are. On their grammar they have something like this:
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`
Note: You can see that here, at the standard prelude.
What they mean on the error message is you can't join infixl 7
elements with infixl 6
, that's would be the same reason that you can't do something like this:
Prelude> 5 * +3
You will get this error:
parse error on input `+'
Wait, if that is a sintax error, why the error message is different?
Well, it seems that the unary "-" operator
is very special in haskell (as other answers said) and is being used on other parts of the grammar, so, in theory this will go to a different branch of the syntax tree and will throw an error somewhere else.
If you want to read more about the unary "-" operator
you can go here.
The rule is that you cannot use a -
operator (Haskell's only unary operator) near a binary operator.
Since you can define new operators in Haskell, the reason for this rule is that otherwise it could introduce a potential parsing ambiguity. Suppose you didn't use any spaces and specified 5*-3
.
Would that mean 5 * -3
or 5 *- 3
?
A rule of thumb is to put negative numbers between parenthesis when they are preceded by a function application or an operator of higher precedence. This has been working for me so far.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With