erste Note Lassen Sie sich, dass es funktioniert auch mit einem cons
außen:
(def fibs (cons 0 (lazy-seq (cons 1 (map + fibs (rest fibs))))))
sie schafft auch, dass lazy-seq
ein Makro (offensichtlich, da sie nicht die Argumente nicht auswertet) und setzt das body
(das Argument (s) zu lazy-seq
) zu einer Funktion.
Wenn Sie jetzt ein Element aus dieser Sequenz "anfordern", wird die Funktion einmal aufgerufen und nachfolgende Aufrufe geben den zwischengespeicherten Wert zurück.
Offensichtlich, nur einmal, dass die Funktion etwas zurückgibt, haben Sie einen Wert verfügbar. Nun, was passiert in unserem schlechten Fall:
Stellen Sie sich clojure ist in der Mitte der Bewertung der Funktion zum allerersten Mal. Die erste Sache, die es benötigt, ist +
, fibs
und (rest fibs)
, um dies an Nachteile zu übergeben. Jetzt wird clojure sehen, dass fibs
eine faule Sequenz ist und rufe sie auf! Dies liegt daran, dass Sie sich gerade in Ihrem ersten Aufruf befinden und nicht zurückgekehrt sind. Dies verursacht eine unendliche Rekursion.
Die Lösung ist einfach: Stellen Sie sicher, dass ein reales Element am Anfang der Liste vorhanden ist, so dass die beiden Ausdrücke fibs
und (rest fibs
) etwas zurückgeben können. Insbesondere die rest
von (cons 1 whatever)
wird whatever
without realizing a single element (wichtig, da sonst wir das gleiche Problem wieder haben) zurückgeben.
Was versuchen Sie mit 'Lazy-Seq' zu erreichen? Es scheint gut zu laufen, wenn Sie es einfach entfernen. – jmargolisvt
@jmargolisvt Auf meinem repl (clojure 1.6) funktioniert der Code '(def fabs (cons 0 (Nachteile 1 (map + fabs (rest fibs))))) nicht. Lazy-seq ist notwendig, denke ich, weil es die Berechnung des Streams verzögert, sonst wird es nicht funktionieren, indem es die Fibs in Form von Fibs selbst definiert – Matteo