如果我从这样的函数返回一个lazy-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来懒散地循环从permutations
函数返回的内容吗?
答案 0 :(得分:6)
您的循环重复代码会懒惰地评估该列表。
你可以自己尝试一下。每次通过添加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"
如您所见,“返回一个值”和值行是交错的。可以使用doall
强制评估惰性seq。如果你循环遍历(doall (permutations [1 2 3]))
,首先它会打印所有“返回值”行,然后只打印值。