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?