是否假设了懒惰序列?

时间:2011-12-18 16:37:24

标签: clojure

我可以安全地假设

(gen-sym-map (gen-acct-num-sym @sym-count (gen-acct-nums 10)) 100.00)
执行

我有一个懒惰的序列,还是gen-sym-map会在lazy-seq函数调用中返回结果映射?

(defn gen-acct-nums [range-end-idx]
    (vec (range 10000 (+ 10000  range-end-idx 1))))

(defn random-acct-num [acct-nums]
    (nth acct-nums (.nextInt random (count acct-nums))))

(defn gen-acct-num-sym [num-syms acct-nums]
    (loop [snum num-syms acct-num-lis []]
        (if (= snum 0)
                acct-num-lis
                (recur (dec snum) (conj acct-num-lis (random-acct-num acct-nums))))))

(defn gen-sym-map-day [acct-nums starting-bal]
    (reduce
        (fn [sym-map one-acct-num]
            (let [trans (random-trans )
                  amt   (random-amount )]
                (conj sym-map { one-acct-num (vector trans amt starting-bal) } )))
        {}
        acct-nums))

(defn gen-sym-map [acct-nums starting-bal]
    (loop [day-count-left @sym-day-count current-day 1 sym-map-local  {}]
        (if (= day-count-left 0)
            sym-map-local
            (recur (dec day-count-left) (inc current-day)
                    (conj sym-map-local {(gen-map-key current-day)
                                    (gen-sym-map-day acct-nums starting-bal)} )))))

1 个答案:

答案 0 :(得分:4)

在这种情况下你得到一个懒惰的序列。

这是出于各种原因:

  • 您正在制作地图。地图不是懒惰的,只有序列。
  • 你的大多数函数都是使用loop / recur编写的,这些函数本质上是命令式的,非惰性的。
  • 同样值得注意的是vecreducecount也是非懒惰的,因为他们需要消耗整个输入序列。因此,无论何时使用这些功能,您的整个序列都将被实现,您将失去懒惰的好处。

如果你想在Clojure中使用延迟序列,最简单的方法通常是根据产生mapfilter等序列的高阶函数编写代码。大多数序列生成函数默认创建延迟序列。

如果你想构建一个懒惰的序列,你当然可以在lazy-seq中包装东西,但这需要以下内容:

  • 您的输出必须采用序列
  • 的形式
  • 你有办法懒惰地构建你的输出而没有意识到完整的结果(否则使用lazy-seq是毫无意义的......)

lazy-seq的经典用法是使用一些高阶函数和递归来定义(可能是无限的)惰性序列,例如:如下:

(def fibs (concat [1 2] (lazy-seq (map + fibs (next fibs)))))