[Haskell-cafe] Left Associativity and Precendence

4 views
Skip to first unread message

Steven Leiva

unread,
Oct 22, 2016, 2:59:25 PM10/22/16
to haskel...@haskell.org
Hi folks, 

Haskell beginner here. I ran across the expression below (from the Haskell Programming From First Principles book), and I was having a hard time putting parenthesis around the expression in order to make the order of application more explicit. 

Here is the expression in question: take 5 . filter odd . enumFrom $ 3

I realize that part of the hang-up that I was having was that I focused solely on the fact that function application is left-associative, and not on the fact that specific functions / operators can have a declared precedence. Once I realized that the $ operator has a declared precedence of 0, the expression took on the following form:

(take 5 . filter odd . enumFrom) $ (3)

Now, everything to the left of the $ operator is simply function application (whitespace) and the function composition operator. I made the same mistake again of ignoring the fact that particular functions / operators can have a declared precedence. Realizing that mistake, and that the function composition has a declared precedence of 9, then the expression took on this form:

((take 5) . (filter odd) . (enumFrom)) $ (3)

So, the general rule that I took away from this is that, when trying to imagine how an expression reduces to normal form, function application does indeed proceed from left to right, but we have to take into account the declared precedence of particular functions / operators.

Is my thinking correct here? Are there any particular holes in this logic? I still don't think I'd be able to figure out "where the parenthesis go" if I was given a new expression with functions / operators with 3 or 4 different declared precedences. For a beginner, is that a huge problem, or is knowledge of the concept enough?

Tom Ellis

unread,
Oct 22, 2016, 5:35:19 PM10/22/16
to haskel...@haskell.org
On Sat, Oct 22, 2016 at 02:58:35PM -0400, Steven Leiva wrote:
> I still don't think I'd be able to figure out "where the parenthesis go" if
> I was given a new expression with functions / operators with 3 or 4
> different declared precedences. For a beginner, is that a huge problem, or
> is knowledge of the concept enough?

If precedence is not intuitively clear then its badly written code. It's
not the fault of the reader.

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.

Adam Bergmark

unread,
Oct 23, 2016, 9:34:10 AM10/23/16
to Tom Ellis, haskel...@haskell.org
> If precedence is not intuitively clear then its badly written code. It's not the fault of the reader.

I think this is a subjective choice. I will assume that a reader understands that `1 + 2 * 3 = 7'. If he doesn't I think he really ought to take the time and learn the precedences. Some precedences are obvious if you know the types involved; `a + b && c` can not equal `(a + b) && c` in a working Haskell program, here you just need to know the types to figure it out.

A reader will never know the precedence of an expression with operators he is not familiar with but this shouldn't necessarily dictate how you write your code. This generalizes to a lot of decisions you need to make while programming.

I'd recommend to start by learning precedences of operators in Prelude and then continuing with the rest of base. The combinations of function application (space), function composition (.), and ($) are very important to know by heart.

If you come across an operator you aren't familiar with learn it by experimenting or looking it up. Try to parenthesize or unparenthesize, also for code you write yourself. You will build an intuition as you go.

Cheers,
Adam

Reply all
Reply to author
Forward
0 new messages