Я пытался понять ленивую оценку в Haskell, и я понял ее в основном как оценку только тогда, когда вам нужно. Но при попытке эффективно реализовать фибоначчи я столкнулся с этим (странным?) поведением: Эта реализация:
--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)
будет работать даже при вызове с
fib 20000000
> -70318061090422843
при замене переданных аргументов в рекурсивном вызове:
fib2 :: Int -> Int -> Int -> Int
fib2 x y 0 = x
fib2 x y z = fib2 (x + y) x (z - 1)
приводит к:
fib 20000000
>*** Exception: stack overflow
Почему бы мне не сказать компилятору, чтобы он с нетерпением выполнял первый пример? Почему второй пример не работает, а первый работает?
Для этого я использовал GHCi 8.0.1 в Windows 10.