2010-05-31 3 views
17

Я просматривал некоторые примеры кода Фибоначчи последовательность Clojure:Какая точка ленивого seq в 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? Это строго для целей кеширования?

EDIT: Спасибо за ответы. Моя путаница заключалась в том, что он работал с простым concat из REPL, потому что у меня было предыдущее связывание с fibs в сфере видимости.

ответ

16

lazy-seq на [1 2] не нужен, но на самом деле не больно.

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

7

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

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

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

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

Смежные вопросы