2015-01-11 3 views
4

Если я возвращаю ленивый-SEQ из функции, как это:Clojure - с помощью петли и повторялся с ленивой последовательностью

(letfn [(permutations [s] 
       (lazy-seq 
       (if (seq (rest s)) 
       (apply concat (for [x s] 
           (map #(cons x %) (permutations (remove #{x} s))))) 
       [s])))]) 

Если я использую цикл повторение, как показано ниже, будет список будет охотно оцениваемыми?

(loop [perms (permutations chain)] 
     (if (empty? perms) 
     (prn "finised") 
     (recur (rest perms)))) 

Если жадно оценивал, можно ли использовать loop..recur лениво перебирает, что возвращается из функции permutations?

ответ

5

Список лениво оценивается кодом цикла-повтора.

Вы можете попробовать сами. Давайте сделаем permutations что-то напечатаем каждый раз, когда оно возвращает значение, добавив вызов println.

(defn permutations [s] 
    (lazy-seq 
    (if (seq (rest s)) 
    (apply concat (for [x s] 
        (map #(cons x %) (permutations (remove #{x} s))))) 
    (do 
     (println "returning a value") 
     [s])))) 

При использовании loop, давайте печатать значения с мы пробегаем через с (prn (first perms).

(loop [perms (permutations [1 2 3])] 
    (if (empty? perms) 
    (prn "finised") 
    (do 
     (prn (first perms)) 
     (recur (rest perms))))) 

Вот что она печатает:

returning a value 
(1 2 3) 
returning a value 
(1 3 2) 
returning a value 
(2 1 3) 
returning a value 
(2 3 1) 
returning a value 
(3 1 2) 
returning a value 
(3 2 1) 
"finished" 

Как вы можете видеть, «возвращает значение» и строки значение переплетены. Оценка ленивого seq может быть вызвана doall. Если вы зацикливаетесь на (doall (permutations [1 2 3])), сначала он печатает все строки «возврат значения» и только значения.

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