Функционально-локальная, самореферентная, ленивая последовательность Фибоначчи

Я хотел бы создать функцию, которая возвращает лениво расширенную бесконечную последовательность чисел Фибоначчи.

Прямо сейчас я могу сделать свою последовательность доступной в пространстве имен верхнего уровня следующим образом:

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

Однако это означает, что если я начну потреблять много из них, я потеряю контроль над сборкой мусора.

Я хочу сделать что-то вроде:

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

Это явно не будет работать, потому что я в конечном итоге создаю O (2 ^ n) последовательностей. Я думаю, что спрашиваю, как создать само-ссылочную ленивую последовательность в пространстве имен локальной функции. Что я должен делать?

РЕДАКТИРОВАТЬ: Хотя мне нравится популярное решение, опубликованное Амаллой и найдено по всему Интернетуdefn fibs [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))Меня интересует версия, похожая на канонический способ Haskell:

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

Это то, что я пытался выполнить с моей первоначальной функцией. Для меня решение с итерацией карты выглядит следующим образом: «добавьте два предыдущих элемента, чтобы создать новый». и решение для ленивого кота читается как «присоединиться к потоку с его первым запаздыванием». Как я могу "присоединиться к потоку с его первой задержкой"? не имея последовательности в пространстве имен верхнего уровня?

Ответы на вопрос(5)

Ваш ответ на вопрос