2010-05-31 3 views
17

나는 몇 가지 예를 들어 피보나치 시퀀스의 Clojure 코드를 찾고 있어요 :clojure에서 lazy-seq의 요점은 무엇입니까?

(def fibs (lazy-cat [1 2] (map + fibs (rest fibs)))) 

나는 일반적으로 진행되고 있지만, lazy-cat의 요점을 파악하지 않는 것을 이해합니다. 정확히 lazy-seq을 성취는 무엇

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

: 나는 lazy-cat가 이런 식으로 번역되는 매크로 것을 알고? lazy-seq이 없어도 느리게 평가됩니다. 이것은 엄격하게 캐싱 목적입니까?

편집 : 답변 해 주셔서 감사합니다. 내 혼란은 REPL에서 일반 concat으로 작동한다는 것이 었습니다. 범위에있는 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)))) 
다음

FIB를 아직 결합하지 않기 때문에이 작동하지 않고 따라서 나중에 두 개의 참조가 실패합니다.

그러나 fibs에 대한 참조는 실제로 나중에 시퀀스가 ​​소비 될 때만 확인되고 fibs는 이미 지연 시퀀스로 정의되어 있기 때문에 작동합니다.

관련 문제