Наткнулся на эту интересную реализацию генератора Фибоначчи в clojure. Немного сложно понять часть ссылки на себя. Любая помощь в ментальном моделировании была бы очень полезна.
(def fib-seq
(lazy-cat [0 1] (map + (rest fib-seq) fib-seq)))
Наткнулся на эту интересную реализацию генератора Фибоначчи в clojure. Немного сложно понять часть ссылки на себя. Любая помощь в ментальном моделировании была бы очень полезна.
(def fib-seq
(lazy-cat [0 1] (map + (rest fib-seq) fib-seq)))
Макрорасширение (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)
Надеюсь это поможет.