Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does MC Haskell function result in stack overflow

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
like image 808
jamesfake namesmith Avatar asked Apr 30 '26 06:04

jamesfake namesmith


2 Answers

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.

like image 113
Willem Van Onsem Avatar answered May 02 '26 03:05

Willem Van Onsem


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.

like image 30
Robin Zigmond Avatar answered May 02 '26 03:05

Robin Zigmond



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!