Funktionslokale, selbstreferenzielle, faule Fibonacci-Sequenz

Ich möchte eine Funktion erstellen, die eine verzögert erweiterte unendliche Folge von Fibonacci-Zahlen zurückgibt.

Im Moment kann ich meine Sequenz im Top-Level-Namespace wie folgt verfügbar machen:

(def fibonacci-numbers
  (lazy-cat [0 1] (map + fibonacci-numbers (rest fibonacci-numbers))))

Dies bedeutet jedoch, dass ich die Kontrolle über die Speicherbereinigung verliere, wenn ich anfange, viele davon zu konsumieren.

Ich möchte etwas machen wie:

(defn fibonacci-numbers-fn []
  (lazy-cat [0 1] (map + (fibonacci-numbers-fn) (rest (fibonacci-numbers-fn)))))

Dies wird eindeutig nicht funktionieren, da ich am Ende O (2 ^ n) -Sequenzen erstellen werde. Ich glaube, ich frage mich, wie man eine selbstreferenzielle Lazy-Sequenz in einem funktionslokalen Namespace erstellt. Was soll ich machen?

BEARBEITEN: Obwohl ich die beliebte Lösung, die von amalloy gepostet und über das Internet gefunden wurde, magdefn fibs [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))Ich bin an einer Version interessiert, die der kanonischen Haskell-Version ähnelt:

fibonaccis = 0 : 1 : zipWith (+) fibonaccis (tail fibonaccis)

Dies ist, was ich mit meiner ursprünglichen Funktion erreichen wollte. Für mich lautet die Map-Iterate-Lösung "Addiere die beiden vorherigen Elemente, um ein neues Element zu erstellen" und die Lazy-Cat-Lösung "Join a Stream with its first lag". Wie kann ich "einem Stream mit seiner ersten Verzögerung beitreten", ohne die Sequenz im Namespace der obersten Ebene zu haben?

Antworten auf die Frage(5)

Ihre Antwort auf die Frage