I've been trying to understand lazy evaluation in Haskell and I understood it basically as only evaluate when you have to. But when trying to implement fibonacci efficiently I came across this (weird?) behaviour: This Implementation:
--wrapper function used by both implementations
fib :: Int -> Int
fib x = if x < 0 then 0 else fib2 0 1 x
fib2 :: Int -> Int -> Int -> Int
fib2 x y 0 = x
fib2 x y z = fib2 y (x + y) (z - 1)
will work even when called with
fib 20000000
> -70318061090422843
while swapping the passed arguments in the recursive call:
fib2 :: Int -> Int -> Int -> Int
fib2 x y 0 = x
fib2 x y z = fib2 (x + y) x (z - 1)
results in:
fib 20000000
>*** Exception: stack overflow
Why don't I have to tell the compiler to eagerly evaluate in the first example? Why does the second example not work while the first does?
I used the GHCi 8.0.1 on Windows 10 for this.