使用reduce避免clojure中的StackOverflowError

Mat*_*teo 2 clojure

简单的代码

(reduce concat (take 10000 (repeat '(1))))
Run Code Online (Sandbox Code Playgroud)

导致StackOverflowError.假设我有一个很大的列表列表,就像我在这个例子中获得的列表一样take.我怎么能在我尝试的时候将它们合并到一个列表中?

lee*_*ski 7

问题是concat返回一个懒惰的seq(并在函数实现之前堆叠函数调用).您可以通过实现连接集合来修复它:

(reduce (comp doall concat) (take 10000 (repeat '(1))))

但它真的很慢.

在你的情况下,我宁愿使用这样的东西:

(reduce into [] (take 10000 (repeat '(1))))

它会急切地将每个集合中的所有元素逐一添加到结果向量中.

否则(如果reduce用途不是为了某些特殊的额外目的)你可以这样做:

(apply concat (take 10000 (repeat '(1))))

这导致了一次调用concat,产生了一个懒惰的seq