Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why it is impossible to multiply negative numbers in haskell without brackets

Tags:

syntax

haskell

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>
like image 792
bessarabov Avatar asked Sep 27 '14 10:09

bessarabov


People also ask

How do I enter negative numbers in Haskell?

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) .

What do brackets mean around a negative number?

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.

Why do negative numbers get smaller?

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.


Video Answer


4 Answers

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)
like image 127
Don Stewart Avatar answered Oct 02 '22 09:10

Don Stewart


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.

like image 34
Gepser Hoil Avatar answered Oct 02 '22 08:10

Gepser Hoil


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?

like image 22
Ferruccio Avatar answered Oct 02 '22 07:10

Ferruccio


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.

like image 29
mljrg Avatar answered Oct 02 '22 08:10

mljrg