clojure-使用循环并使用惰性序列重复

clojure-使用循环并使用惰性序列重复,clojure,lazy-evaluation,Clojure,Lazy Evaluation,如果我从如下函数返回惰性seq: (letfn [(permutations [s] (lazy-seq (if (seq (rest s)) (apply concat (for [x s] (map #(cons x %) (permutations (remove #{x} s))))) [s])))

如果我从如下函数返回惰性seq:

(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来惰性地循环从
置换
函数返回的内容吗?

列表由循环递归代码惰性地求值

你可以自己试试。让我们通过添加
println
调用,在每次返回值时进行
permutations
打印

(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(第一次烫发)

下面是它打印的内容:

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"
如您所见,“返回值”和值行是交错的。可以使用
doall
强制执行惰性seq的计算。如果循环
(doall(置换[1 2 3]))
,它首先打印所有“返回值”行,然后才打印值

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"