Le funzioni foldl
e foldr
sono elenco- consumatori. Come svenningsson's answer giustamente sottolinea, unfoldr
è una lista- produttore che è adatto per catturare la struttura -recursive co di fibs
.
Tuttavia, dato che foldl
e foldr
sono polimorfici nei loro tipi di ritorno, vale a dire ciò che producono consumando un elenco, è ragionevole chiedersi se potrebbero essere utilizzati per consumare un elenco e generarne un altro. Qualcuno di questi elenchi prodotti potrebbe essere infinito?
Guardando la definizione di foldl
foldl :: (a -> b -> a) -> a -> [b] -> a
foldl f a [] = a
foldl f a (b : bs) = foldl f (f a b) bs
vediamo che per foldl
per produrre qualcosa, la lista che consuma deve essere finito. Quindi se foldl f a
produce un output infinito, è perché a
è infinito o perché lo f
a volte esegue la generazione di liste infinite.
E 'una storia diversa con foldr
foldr :: (b -> a -> a) -> a -> [b] -> a
foldr f a [] = a
foldr f a (b : bs) = f b (foldr f a bs)
che ammette la possibilità pigro che f
potrebbe generare una certa uscita per ogni b
consumato dall'ingresso. Operazioni come
produrre un po 'di output per ogni input, fornire un output infinito da input infinito.
Una persona sfacciata può così esprimere qualsiasi ricorsione infinita come una foldr
non ricorsiva su una lista infinita. Ad esempio,
foldr (\ _ fibs -> 1 : 1 : zipWith (+) fibs (tail fibs)) undefined [1..]
(Edit:. O, se è per questo
foldr (\_ fib a b -> a : fib b (a + b)) undefined [1..] 1 1
che è più vicino alla definizione in questione)
anche se questa osservazione, pur vero, non è certo indicativo di uno stile di programmazione sano.
Anche se questo è interessante, v'è in realtà un modo migliore per fare questo, che è quello di utilizzare la [soluzione in forma chiusa per trovare i numeri di Fibonacci] (http : //en.wikipedia.org/wiki/Fibonacci_number#Computation_by_rounding) –
@AndrewWalker, con aritmetica in virgola mobile, non è una soluzione esatta. – huon
Nota che in un linguaggio funzionale non rigido come Haskell, non c'è motivo di evitare la ricorsione per ragioni di efficienza, ma va bene evitarlo per ragioni stilistiche. – AndrewC