Clojure 如何创建惰性seq向量

Clojure 如何创建惰性seq向量,clojure,lazy-sequences,Clojure,Lazy Sequences,按预期运行此操作: (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] (

按预期运行此操作:

(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))

这会导致堆栈溢出。为什么?

主要原因是向量不是惰性的——因此
调用贪婪地消耗了
长序列向量
产生的递归序列,并导致堆栈溢出。因此,不可能创建无限向量(通常,只有当无限数据结构是惰性的或循环的时,才能创建无限数据结构)

它在第一个示例中起作用,因为
cons
在考虑惰性序列的前端时非常乐意表现出惰性,因此序列可以是无限的

假设你真的想要一个无限的向量序列,我建议如下:

(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)})))
我更喜欢这样做,因为它避免了
惰性seq
/
cons
样板文件,避免了递归,并且在表达函数的功能时更加清晰。。。如果你愿意的话,它更具“声明性”。您也可以以类似的方式使用
map