clojure - 使用循环并通过惰性序列重复出现
clojure - using loop and recur with a lazy sequence
如果我从这样的函数返回惰性序列:
(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
函数返回的内容吗?
该列表由您的循环递归代码延迟计算。
你可以自己试试看。让我们通过添加 println
调用让 permutations
每次 returns 打印一些值。
(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"
如您所见,"returning a value" 和值线是交错的。惰性序列的评估可以用 doall
强制执行。如果您遍历 (doall (permutations [1 2 3]))
,首先它会打印所有 "returning a value" 行,然后才打印值。
如果我从这样的函数返回惰性序列:
(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
函数返回的内容吗?
该列表由您的循环递归代码延迟计算。
你可以自己试试看。让我们通过添加 println
调用让 permutations
每次 returns 打印一些值。
(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"
如您所见,"returning a value" 和值线是交错的。惰性序列的评估可以用 doall
强制执行。如果您遍历 (doall (permutations [1 2 3]))
,首先它会打印所有 "returning a value" 行,然后才打印值。