I am working my way through the Haskell book and am on chapter 8. While doing the exercises I noticed something I didn't understand.
Why does this result in stack overflow
mc x | x>100 = x-10
| otherwise = mc $ mc x+11
but this doesn't
mc x | x>100 = x-10
| otherwise = mc $ mc (x+11)
I think it has something to do with x+11 not being evaluated in the first example but aren't expressions like that always evaluated
for example
Prelude> id 43+94
137
The first expression
mc $ mc x+11
is interpreted as
mc ((mc x) + 11)
since function application takes precedence over operators.
The second expression
mc $ mc (x+11)
is interpreted as:
mc (mc (x+11))
The first indeed will never get evaluated, since if you write:
mc x | x > 100 = x-10
| otherwise = mc ((mc x) + 11)
then you define mc x in terms of mc x. Unless that mc x in that expression is not evaluated, you thus will call mc x, when calculating mc x, and thus it will keep making calls.
It's purely about operator precedence. In particular, function application takes precedence over all operators. So this:
mc x+11
is actually parsed as
(mc x)+11
and the fact that you tried to "visually" indicate the desired grouping by spacing or lack of it makes no difference. This of course is why your second version works better, since you explicitly indicated the grouping you want.
Of course, the unintended interpretation means that, for x <= 100, in order to evaluate mc x the compiler has to first evaluate mc x, and so on ad infinitum. Hence the eventual stack overflow.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With