微调范围的惰性

fine tune range`s laziness

此代码:

(first (map (fn [d] 
              (apply * (repeat d 10)))
            (range)))

产生整数溢出异常,而这段代码:

(first (map (fn [d] 
              (apply * (repeat d 10)))
            (range 0 1)))

1 岁

两个代码都应为 1,但出于某种原因,范围的惰性有一种奇怪的行为。它似乎一次获取大量数据而不是一个数据。是否可以使 range 以所需的方式运行?

range 被分块,作为性能优化。有几种方法可以解决这个问题,包括使用 (iterate inc 0)unchunk(有几个版本,这个是从 math.combinatorics 复制的)

(defn unchunk
  [s]
  (lazy-seq
    (when (seq s)
      (cons (first s)
            (unchunk (rest s))))))
user=> (first (map (fn [d]
                     (apply * (repeat d 10)))
                   (unchunk (range)))
1