Как мысленно смоделировать этот генератор Фибоначчи clojure?

Наткнулся на эту интересную реализацию генератора Фибоначчи в clojure. Немного сложно понять часть ссылки на себя. Любая помощь в ментальном моделировании была бы очень полезна.

(def fib-seq
 (lazy-cat [0 1] (map + (rest fib-seq) fib-seq)))

person Kannan Ramamoorthy    schedule 12.06.2019    source источник


Ответы (1)


Макрорасширение (lazy-cat [0 1] (map + (rest fib-seq) fib-seq) приводит к:

(concat (lazy-seq [0 1]) (lazy-seq (map + (rest fib-seq) fib-seq)))

(map + coll1 coll2) возвращает новую коллекцию, в которой первый элемент первого списка добавляется к первому элементу второго списка, второй элемент первого списка добавляется ко второму элементу второго списка и так далее.

user> (map + [1 2 3 4] [1 2 3 4])
(2 4 6 8)

Итак, мы начинаем с 0 и 1, а затем получаем первый из остальных fib-seq (1) к первому элементу fib-seq (0), это приводит к 1. Затем мы снова получаем следующий элемент fib-seq, который является 1, который мы только что поняли, и добавляем его ко второму элементу fib-seq (1), что приводит к 2, и так далее.

Поэтому мы лениво конкатируем [0 1] к результату суммирования двух коллекций после сдвига на 1:

[0 1] <+ concat>
[1 + 0
 1 + 1
 2 + 1
 3 + 2
 ...]
user> (take 10 fib-seq)
(0 1 1 2 3 5 8 13 21 34)

Надеюсь это поможет.

person Erwin Rooijakkers    schedule 13.06.2019