Какой смысл ленивого-seq в clojure?

Я просматриваю некоторый пример последовательность 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, потому что у меня была предыдущая привязка к выдумкам в объеме.

17
задан dbyrne 31 May 2010 в 18:22
поделиться

2 ответа

lazy-seq на [1 2] не нужен, но на самом деле не повредит.

lazy-seq на (map + fibs (rest fibs)) очень важен; без него вызов функции будет оценен до того, как fibs будет привязан к значению, что вызовет исключение. Если заключить его в lazy-seq , вызов будет отложен до тех пор, пока значение не понадобится, и fibs будет иметь значение в этой точке.

16
ответ дан 30 November 2019 в 13:27
поделиться

Как я понимаю (а я, признаться, еще относительный новичок в Clojure!), если вы попробуете сделать следующее:

(def fibs (concat [1 2] (map + fibs (rest fibs))))

Тогда это не сработает, потому что fibs еще не связан, и поэтому две последующие ссылки на него не сработают.

Однако ленивая версия, которую вы приводите, будет работать, потому что ссылки на fibs фактически разрешаются только позже, когда последовательность потребляется - и к этому моменту fibs уже успешно определена как ленивая последовательность.

7
ответ дан 30 November 2019 в 13:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: