uczę Haskell, i napisałem prostą funkcję Fibonacciego:Haskell Fibonacciego wydaje się powolny
fib :: Int -> Int
fib 1 = 1
fib 0 = 0
fib n = (fib (n-1)) + (fib (n-2))
Wydaje skompilować OK, a załadunek ten skrypt do GHCI REPL mogłem poeksperymentować z kilkoma numerami . Próbowałem
fib 33
i był zaskoczony, że zajęło to około 4 sekund, uzyskując rezultat. (Przepraszam, nie wiem jeszcze, jak czasować funkcję w Haskell, więc liczyłem się).
Fib 33 nie jest szczególnie podatkowy. Odpowiedź jest mniejsza niż 4 miliony. Zakładam więc, że mój kod nie jest napisany zbyt dobrze lub jest jakiś problem ze sposobem, w jaki robię rekurencję (no cóż, nie jest dobrze napisane, że nie bierze pod uwagę liczb całkowitych ujemnych). Pytanie brzmi: dlaczego jest wolny? Każda pomoc doceniona.
To pytanie wydaje się być dobry dla inspekcja kodu. – Alexander
Patrząc na swój kod, wyobraź sobie, jak często oblicza się na przykład 'fib (5)'. W każdej iteracji obliczasz ponownie wszystkie "wewnętrzne" liczby fibonaccich. – WeSt
Powinieneś użyć klasycznej wersji nieskończonej listy leniwej: 'fibs = 0: 1: zipWith (+) fibs (tail fibs)' with 'fib n = fibs !! n'. Zobacz [wiki haskell o sekwencji Fibonacciego] (https://www.haskell.org/haskellwiki/The_Fibonacci_sequence).Zabawne jest to, że Fibonacci słynie z tej sekwencji, która była zaledwie małym ćwiczeniem w książce, z której powinien być znany, co wprowadziło wartość dodaną do Europy Zachodniej. – AndrewC