Função-local, auto-referencial, seqüência de fibonacci preguiçoso

Eu gostaria de criar uma função que retorna uma seqüência infinita preguiçosamente estendida de números de Fibonacci.

No momento, posso disponibilizar minha sequência no namespace de nível superior da seguinte forma:

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

No entanto, isso significa que se eu começar a consumir muitos deles, perco o controle sobre a coleta de lixo.

Eu estou procurando fazer algo como:

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

Isso claramente não funcionará porque acabarei criando seqüências O (2 ^ n). Eu acho que estou perguntando como criar uma seqüência preguiçosa auto-referencial em um namespace local de função. O que devo fazer?

EDIT: Embora eu goste da solução popular postada por amalloy e achei toda a internetdefn fibs [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))), Estou interessado em uma versão semelhante à maneira canônica do Haskell:

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

Isso é o que eu estava tentando realizar com a minha função original. Para mim, a solução de iteração de mapa é como "adicione os dois elementos anteriores para criar um novo" e a solução "preguiçosa" se assemelha a "unir um fluxo com seu primeiro atraso". Como posso "ingressar em um fluxo com o primeiro atraso" sem ter a sequência no namespace de nível superior?

questionAnswers(5)

yourAnswerToTheQuestion