2012-11-16 5 views
6

Ich versuche, die Ausführung des folgenden Codes zu verstehen:die Ausführung einer faulen Fibonacci-Implementierung in Clojure Verständnis

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

Dies ist, was würde ich die Ausführung wie

[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 .... 
aussehen erwarten

Das ist offensichtlich falsch, da das Ergebnis falsch ist. Die einzige Ausführung ich kommen könnte mit, dass das richtige Ergebnis erzeugt, ist dies:

[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 .... 

Ist das eine richtige „Darstellung“ des Staates von Kopf und Schwanz während der Ausführung? Wenn ja, warum gibt (rest fibs) ein einzelnes Element zurück? Liegt es an einem rekursiven Aufruf wie (Ruhe (Ruhe (Ruhe [1 1 2 3])))?

Antwort

6

Fibs ist (0 1 ...) (wegen der (concat [0 1] ...) am Anfang). (rest fibs) ist (1 ...). Dann (map + fibs (rest fibs)) ist

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

So fibs ist (0 1 1 ...). Da wir den nächsten Punkt bekam, können wir berechnen, noch ein anderes:

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

Und es geht weiter ...

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

Denken Sie an fibs , als ob es schon da war, und der Staat von (map + fibs (rest fibs) als auf der Liste der bereits vorhandenen fibs (das ist in Ordnung, weil es am Ende berechnet alles, was wir auf dem Weg brauchen).

Es könnte auch helfen, nur die beiden Sequenzen aufschreiben:

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

(Ich würde zeichnen hier Pfeile, um anzuzeigen, was wir schon bekommen und wo das Ergebnis geht, aber ich kann das nicht hier so gut).

Verwandte Themen