Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Precedence of function application

In order to illustrate function application has the highest precedence in Haskell the following example was provided (by schoolofhaskell):

sq b = b * b
main = print $
-- show
    sq 3+1 
-- /show

The result here is 10.

What puzzles me is that the argument constitutes a function application too. Consider the operator + being a short-cut of a function. So when the argument is taken, I would expect that its function application now takes precedence over the original one.

Written that way it delivers the expected result:

sq b = b * b
main = print $
    sq ((+) 3 1 )

Any explanation?

like image 986
Andreas Röhler Avatar asked Oct 15 '25 03:10

Andreas Röhler


2 Answers

What puzzles me is that the argument constitutes a function application too. Consider the operator "+" being a short-cut of a function.

I think this is the heart of the misunderstanding (actually, very good understanding!) involved here. It is true that 3 + 1 is an expression denoting the application of the (+) function to 3 and 1, you have understood that correctly. However, Haskell has two kinds of function application syntax, prefix and infix. So the more precise version of "function application has the highest precedence" would be something like "syntactically prefix function application has higher precedence than any syntactically infix function application".

You can also convert back and forth between the two forms. Each function has a "natural" position: names with only symbols are naturally syntactically infix and names with letters and numbers and the like are naturally syntactically prefix. You can turn a naturally prefix function to infix with backticks, and a naturally infix function to prefix with parentheses. So, if we define

plus = (+)

then all of the following really mean the same thing:

3 + 1
3 `plus` 1
(+) 3 1
plus 3 1

Returning to your example:

sq 3+1

Because sq is naturally prefix, and + is naturally infix, the sq application takes precedence.

like image 94
Daniel Wagner Avatar answered Oct 16 '25 23:10

Daniel Wagner


So when the argument is taken, would expect that its function application now takes precedence over the original one.

The Haskell grammar [Haskell report] specifies:

exp10
  → … 
  | …  
  | fexp
fexp
  →  [fexp] aexp   (function application)

This means that function application syntax has precedence 10 (the superscript on the exp10 part).

This means that, when your expression is parsed, the empty space in sq 3 takes precedence over the + in 3+1, and thus sq 3+1 is interpreted as (sq 3) + 1 which semantically means that it squares 3 first, and then adds 1 to the result, and will thus produce 10.

If you write it as sq (3 + 1) or in canonical form as sq ((+) 3 1) it will first sum up 3 and 1 and then determine the square which will produce 16.

like image 22
Willem Van Onsem Avatar answered Oct 16 '25 22:10

Willem Van Onsem