Я просматриваю некоторый пример последовательность Fibonacci clojure код:
(def fibs (lazy-cat [1 2] (map + fibs (rest fibs))))
Я обычно понимаю то, что продолжается, но не понимайте назначение lazy-cat
. Я знаю это lazy-cat
макрос, который переводит во что-то вроде этого:
(def fibs (concat (lazy-seq [1 2]) (lazy-seq (map + fibs (rest fibs)))))
Что точно lazy-seq
выполнение? Это было бы все еще оценено лениво даже без lazy-seq
? Это строго для кэширования целей?
Править: Спасибо за ответы. Мой беспорядок состоял в том, что это работало с плоскостью concat
от REPL, потому что у меня была предыдущая привязка к выдумкам в объеме.
lazy-seq
на [1 2]
не нужен, но на самом деле не повредит.
lazy-seq
на (map + fibs (rest fibs))
очень важен; без него вызов функции будет оценен до того, как fibs
будет привязан к значению, что вызовет исключение. Если заключить его в lazy-seq
, вызов будет отложен до тех пор, пока значение не понадобится, и fibs
будет иметь значение в этой точке.
Как я понимаю (а я, признаться, еще относительный новичок в Clojure!), если вы попробуете сделать следующее:
(def fibs (concat [1 2] (map + fibs (rest fibs))))
Тогда это не сработает, потому что fibs еще не связан, и поэтому две последующие ссылки на него не сработают.
Однако ленивая версия, которую вы приводите, будет работать, потому что ссылки на fibs фактически разрешаются только позже, когда последовательность потребляется - и к этому моменту fibs уже успешно определена как ленивая последовательность.