Funkcjonalnie-lokalna, samo-referencyjna, leniwa sekwencja fibonacci

Chciałbym stworzyć funkcję, która zwraca leniwie wydłużoną nieskończoną sekwencję liczb Fibonacciego.

Teraz mogę udostępnić moją sekwencję w przestrzeni nazw najwyższego poziomu w następujący sposób:

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

Oznacza to jednak, że jeśli zacznę zużywać ich dużo, tracę kontrolę nad zbieraniem śmieci.

Szukam czegoś takiego:

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

To oczywiście nie zadziała, ponieważ skończę tworząc sekwencje O (2 ^ n). Myślę, że pytam, jak utworzyć leniwą sekwencję samoodniesienia w lokalnej przestrzeni nazw funkcji. Co powinienem zrobić?

EDYCJA: Chociaż lubię popularne rozwiązanie opublikowane przez amalloy i znalezione w całym Interneciedefn fibs [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))), Interesuje mnie wersja podobna do kanonicznego sposobu Haskella:

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

Właśnie to próbowałem osiągnąć dzięki mojej oryginalnej funkcji. Dla mnie rozwiązanie mapowania iteracyjnego brzmi: „dodaj poprzednie dwa elementy, aby utworzyć nowy”, a rozwiązanie leniwe-kot brzmi jak „dołącz do strumienia z jego pierwszym opóźnieniem”. Jak mogę „połączyć strumień ze swoim pierwszym opóźnieniem” bez sekwencji w obszarze nazw najwyższego poziomu?

questionAnswers(5)

yourAnswerToTheQuestion