【问题标题】:clojure - using loop and recur with a lazy sequenceclojure - 使用循环并使用惰性序列递归
【发布时间】:2015-01-11 07:06:21
【问题描述】:

如果我从这样的函数返回一个惰性序列:

(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 函数返回的内容吗?

【问题讨论】:

    标签: clojure lazy-evaluation


    【解决方案1】:

    您的循环递归代码会懒惰地评估该列表。

    您可以自己尝试一下。让我们通过添加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 (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 强制评估惰性序列。如果您循环遍历(doall (permutations [1 2 3])),首先它会打印所有“返回值”行,然后才是值。

    【讨论】:

      猜你喜欢
      • 2014-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多