Effective Haskell:

Title: Effective Haskell - Kindle Edition
Chapter: 1 Section: Precedence, Operators, and Fixity

In the first expression, ((((((add add) 1) 2) add) 3) 4), the operations are evaluated from right to left, resulting in 10. In the second expression, (add ((add 1 2) (add 3 4))), the operations are evaluated from left to right, yielding the same result of 10. On the book the first expression is said to be from left to right and the second from right to left: the exact contrary. Could you please help me to understand?

Thank you,
Regards
Fabio

https://devtalk.com/u/rebeccaskinner

@RebeccaSkinner Hi :slight_smile: Sorry I deleted the tag in the first post and I cannot edit it anymore. I hope you saw it. Thank you in advance for your help,
Regards,
Fabio

Hey, I did see this, sorry it took me a couple of days to respond

This example is trying to help you build up an understanding of how function binding works compared to the way that we normally read text.

In the example, we start by writing code like this:

add add 1 2 add 3 4

This particular example is really intended to be informal and to just help you understand some of the errors you get if you accidentally get the fixity of something wrong.

The two examples here are intended to help you get a general sense for the fact that how we apply things is fairly arbitrary. In English, we read things from left to right, and so for native English speakers that’s the way we tend to think about code too. In our example, we start by imagining that we apply things in the same order that we’d encounter things when reading:

((((((add add) 1) 2) add) 3) 4)

In this example, the very first thing is the function add and it takes an argument. The next thing going from left-to-right is another add, so we’d start by passing add in as the first argument to add. This causes a compiler error, since add should get numbers instead of functions.

The second example imagines that function application works by first finding the right-most function, and then applying it’s arguments. In this case, the right-most function is once again add and it’s two arguments are 3 and 4. The next right-most function would be add with arguments 1 and 2. In this world though, we’d run into a different error. After calling add 1 2 we’d get a number, 3, but we’re trying to apply the result of add 3 4 to it. It’s broken in a different way, but also doesn’t work!

Ultimately, both of these examples are just thought exercises to help you realize that things like associativity and binding precedence are arbitrary choices we have to make. In the next section, when you start working with operators, you’ll start to work through more examples that should give you a more intuitive understanding of this. If you’re still finding this explanation a bit hard to follow I’d encourage you to move on and work through the rest of the chapter to see if some of the more hands-on work helps it resonate better.

I hope that’s helpful!

Thank you Rebecca :slight_smile:
Regards
Fabio