【问题标题】:How can I create a lazy-seq vector如何创建惰性序列向量
【发布时间】:2012-08-25 18:25:18
【问题描述】:

按预期运行:

(defn long-seq [n]
  (lazy-seq (cons 
             (list n {:somekey (* n 2)})
             (long-seq (+ n 1)))))
(take 3 (long-seq 3))
; => ((3 {:somekey 6}) (4 {:somekey 8}) (5 {:somekey 10}))

但是我想对向量做同样的事情:

(defn long-seq-vec [n]
  (lazy-seq (into 
             (vector (list n {:somekey (* n 2)}))
             (long-seq-vec (+ n 1)))))
(take 3 (long-seq-vec 3))

这给了我一个堆栈溢出。为什么?

【问题讨论】:

    标签: clojure lazy-sequences


    【解决方案1】:

    主要原因是向量不是惰性的 - 所以into 调用贪婪地消耗long-seq-vec 产生的递归序列并导致堆栈溢出。因此,不可能创建无限向量(通常,只有在惰性或循环的情况下才能创建无限数据结构)。

    它在第一个示例中有效,因为 cons 在对惰性序列的前面进行 consing 时非常乐意表现惰性,因此序列可以是无限的。

    假设您实际上想要一个无限的向量序列,我建议您这样做:

    (defn long-seq-vec [n]
      (lazy-seq (cons 
                  (vector n {:somekey (* n 2)})
                  (long-seq-vec (+ n 1)))))
    
    (take 3 (long-seq-vec 3))
    
    => ([3 {:somekey 6}] [4 {:somekey 8}] [5 {:somekey 10}])
    

    或者,您也可以使用 for,它本身就是惰性的:

    (defn long-seq-vec [n]
      (for [x (iterate inc n)]
        (vector x {:somekey (* x 2)})))
    

    我更喜欢这个,因为它避免了 lazy-seq/cons 样板,避免了递归,并且在表达你的函数的作用时稍微更清楚......如果你愿意,它会更“声明性”一点。你也可以用类似的方式使用map

    【讨论】:

      猜你喜欢
      • 2011-03-06
      • 2013-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多