Función local, autorreferencial, secuencia perezosa de fibonacci

Me gustaría crear una función que devuelva una secuencia infinita de números de Fibonacci perezosamente extendida.

En este momento, puedo hacer que mi secuencia esté disponible en el espacio de nombres de nivel superior, como este:

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

Sin embargo, esto significa que si comienzo a consumir muchos de ellos, pierdo el control sobre la recolección de basura.

Estoy buscando hacer algo como:

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

Esto claramente no funcionará porque terminaré creando secuencias O (2 ^ n). Creo que estoy preguntando cómo crear una secuencia perezosa autorreferencial en un espacio de nombres con función local. ¿Qué tengo que hacer?

EDITAR: Aunque me gusta la solución popular publicada por amalloy y encontrada en todo el Internetdefn fibs [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))Me interesa una versión similar a la forma canónica de Haskell:

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

Esto es lo que estaba tratando de lograr con mi función original. Para mí, la solución de iteración de mapas se lee como "agrega los dos elementos anteriores para crear uno nuevo" y la solución perezosa se lee como "únete a un flujo con su primer retraso". ¿Cómo puedo "unirme a un flujo con su primer retraso" sin tener la secuencia en el espacio de nombres de nivel superior?

Respuestas a la pregunta(5)

Su respuesta a la pregunta