2012-11-16 13 views
6

Sto cercando di capire l'esecuzione del seguente codice:Comprendere l'esecuzione di un'implementazione Fibonacci pigro in Clojure

(def fibs 
    (concat (lazy-seq [0 1]) (lazy-seq (map + fibs (rest fibs))))) 

Questo è quello che mi aspetterei l'esecuzione a guardare come

[0 1 : (map + [0 1] [1]) => 1 
[0 1 1 : (map + [0 1 1] [1 1]) => 1 2 
[0 1 1 1 2 : (map + [0 1 1 2] [1 1 2]) => 1 2 3 
[0 1 1 1 2 1 2 3 : (map + [0 1 1 2 3] [1 1 2 3]) => 1 2 3 5 
[0 1 1 1 2 1 2 3 1 2 3 5 .... 

Che è ovviamente errato, poiché il risultato è sbagliato. L'unica esecuzione ho potuto venire con quello prodotto il risultato corretto è questo:

[0 1 : (map + [0 1] [1]) => 1 
[0 1 1 : (map + [1 1] [1]) => 2 
[0 1 1 2 : (map + [1 2] [2]) => 3 
[0 1 1 2 3 : (map + [2 3] [3]) => 5 
[0 1 1 2 3 5 .... 

E` una corretta "rappresentazione" dello stato della testa e della coda durante l'esecuzione? In tal caso, perché (rest fibs) restituisce un singolo articolo? È a causa di una chiamata ricorsiva come (riposo (riposo (riposo [1 1 2 3])))?

risposta

6

Fibs è (0 1 ...) (a causa dello (concat [0 1] ...) all'inizio). (rest fibs) è (1 ...). Poi (map + fibs (rest fibs)) è

((+ 0 1) ...) => (1 ...) 

Così FIBS è (0 1 1 ...). Dal momento che abbiamo ottenuto la voce successiva, possiamo calcolare un altro ancora:

(1 (+ 1 1) ...) => (1 2 ...) 

E si va avanti ...

(1 2 (+ 1 2) ...) 

Pensate FIBS come se fosse già lì, e lo Stato di (map + fibs (rest fibs) come spostandoci sulla lista dei fib che già esistono (va bene perché finisce per calcolare tutto ciò di cui abbiamo bisogno sulla strada).

Potrebbe anche aiutare a scrivere in fondo le due sequenze:

(0 1 1 2 3 5 ...) 
+(1 1 2 3 5 ...) 
=(1 2 3 5 8 ...) 

(mi piacerebbe disegnare frecce qui per indicare quello che abbiamo già ottenuto e dove il risultato va, ma non posso farlo qui così bene).

Problemi correlati