Sto appena iniziando a esaminare Haskell. Ho “scritto unimplementazione ingenua di Fibonacci e” ho anche scritto una versione più avanzata uno che utilizza la ricorsione delle chiamate di coda per lefficienza.
module Fibonacci where import System.Environment fibonacci :: Integer -> Integer fibonacci 0 = 0 fibonacci 1 = 1 fibonacci n | n < 0 = error "Cannot find a negative fibonacci number" | otherwise = fibonacci (n - 1) + fibonacci (n - 2) fibonacci" :: Integer -> Integer fibonacci" n | n < 0 = error "Cannot find a negative fibonacci number" | otherwise = fibHelper n 0 1 where fibHelper :: Integer -> Integer -> Integer -> Integer fibHelper n a b | n == 0 = a | otherwise = fibHelper (n - 1) b (a + b) firstNumberFrom :: [String] -> Integer firstNumberFrom [] = 10 firstNumberFrom args = read $ args !! 0 main = do args <- getArgs let num = firstNumberFrom args in putStrLn $ show (fibonacci" num)
Apprezzerei qualsiasi recensione sulla correttezza e sulluso idiomatico.
Commenti
- Qual è il tuo scopo dietro limplementazione di uningenua funzione di Fibonacci? Hai familiarità con i suoi limiti? Hai familiarità con algoritmi di Fibonacci più efficienti?
- Il wiki Haskell ha un articolo con molte implementazioni di Fibonacci differenti: wiki.haskell.org/The_Fibonacci_sequence
Risposta
I molti approcci in main
e firstNumberFrom
può essere unificato:
main = print . fibonacci" . maybe 10 read . listToMaybe =<< getArgs
La ricorsione esplicita in fibbonacci"
viene acquisito da iterate
:
fibbonacci" n = fst $ iterate (\(a,b) -> (b, a+b)) (0,1) !! n