I have 2 snippets of Haskell code.
This one one works fine:
(3+) $ 5
This one throws an error:
3+ $ 5
Why is this happening ? Aren't both of them parsed the same because of the higher precedence of + relative to $ ?
I have 2 snippets of Haskell code.
This one one works fine:
(3+) $ 5
This one throws an error:
3+ $ 5
Why is this happening ? Aren't both of them parsed the same because of the higher precedence of + relative to $ ?
+ and $ are infix operators, and you cannot directly give + one argument on the left to curry it - you need to put it in parentheses as (3+), (+3) or (+) to make it a function that can be used with $. Your second piece of code is syntactically invalid because + cannot be treated as a postfix operator, although you can partially apply it inside parentheses.
If $ had been a function f instead, it would be parsed as 3 + (f 5), but there is no way to parse two operators next to each other.
Short Answer: The expression (3+) is an example of a "section". It is syntactically distinct from usual infix operator syntax (like 2+3) or usual function application by juxtaposition (like sqrt 16), and the enclosing parentheses are not the usual grouping parentheses used for ordering operations. Instead, the parentheses in the section are part of the syntax, and you simply cannot write a section without those enclosing parentheses, just as you cannot write a tuple (1,2) without parentheses.
Very Long Answer:
There are three distinct function call expression syntaxes in Haskell:
f x. In this example, both f and x are expressions consisting of single identifiers. Parentheses are not needed, but can be added without affecting the meaning ((f) (((x)))), and with more complicated expressions, parentheses might be required to get the order of operations right. However, these are "grouping parentheses", part of the syntax of expressions used to order operations, and they are separate from the juxtaposition syntax itself.x / y, and the function represented by the operator / is applied to argument x and the result of that application is applied to argument y. Again, parentheses might be added to the two expression arguments or around the entire resulting expression: ((x) / (y)). In more complicated expressions, they may be required to get the order of operations right. However, again these are "grouping parentheses", part of the syntax of the expressions themselves and not part of the infix operator syntax.(/ 2) and a left section (2 /) consisting of an infix operator and an expression placed next to each other, in either order (operator first or operator last) between parentheses. Note that the parentheses are part of the syntax. A section cannot be written without parentheses, just as a tuple cannot be written without parentheses. A section creates a partially applied function: (2 /) applies the operator / to 2 as if it had appeared on the left-hand side of a more usual infix expression. The result is a function that expects one more argument (the missing right-hand side). Therefore, (2 /) 3 == 2 / 3. Similarly, the section (/ 2) applies the operator / to 2 as if 2 had appeared on the right-hand side of an infix expression. The result is a function expecting the missing left-hand side. Therefore (/ 2) 3 == 3 / 2. To be clear, that's juxtaposition of a section and a number on the left of == versus infix operator syntax on the right.There's never any ambiguity about whether a piece of syntax is juxtaposition within grouping parentheses (i.e., parentheses not part of the syntax) versus a section (i.e., with parentheses part of the syntax). Even though the expressions (f x) and (+ x) look similar, f and x are expressions while + is an operator. Because + is an operator and not an expression, (+ x) must be a section. Likewise, because both f and x are expressions and not operators, (f x) must be juxtaposition placed within grouping parentheses.
There is a further complication. The operator + may be turned into a standalone expression by placing it within parentheses, like (+). Again, the parentheses are part of the syntax. In much the same way that sections (2 +) and (+ 2) turn the operator into a function expression (in this case, of a function of one variable), the syntax (+) turns the operator into the function expression representing the two-argument function associated with the operator. Just as with sections, there's no possibility of confusing (+) (parentheses part of the syntax) with (15) (grouping parentheses) because + is an operator while 15 is an expression.
As a result, the following are all equivalent ways of applying the two operators + and $
(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
In contrast, there's no valid syntactic construction that allows two binary operators to appear next to each other without intervening parentheses, which is why the following is invalid syntax:
3+ $ 5
Bonus trivia #1: The expression 3+$5 is valid syntax, but that's because +$ is considered a new multi-character operator, like ++ or >>=.
Bonus trivia #2: There is one case where two operators may be placed next to each other. A binary operator can be placed next to the unary negation operator -, provided the binary operator is of lower precedence (than the usual precedence for the binary operator -, so lower than precedence level 6).
-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