Clojure 从惰性序列获取所有已实现的值

Clojure 从惰性序列获取所有已实现的值,clojure,Clojure,如何在不知道前五个值已实现的情况下实现所有值(8 2 9 9 2) ;; create lazy infinite seq of random ints (def infi-seq (repeatedly #(rand-int 11))) (take 5 infi-seq) ; => (8 2 9 9 5) 您可以修改或使用 注意,对于非惰性元素在序列前加前缀的情况(如在iterate中),检查ipend是必要的 也许这是: (def foo (iterate inc 1)) (ta

如何在不知道前五个值已实现的情况下实现所有值
(8 2 9 9 2)

;; create lazy infinite seq of random ints
(def infi-seq (repeatedly #(rand-int 11)))
(take 5 infi-seq) ; => (8 2 9 9 5)
您可以修改或使用

注意,对于非惰性元素在序列前加前缀的情况(如在iterate中),检查ipend是必要的


也许这是:

(def foo (iterate inc 1))

(take (count-realized foo) foo)
;=> (1)

(dorun (take 5 foo))
;=> nil

(take (count-realized foo) foo)
;=> (1 2 3 4 5)

整洁但华而不实。它可以在某种程度上固定:

(defn take-realized [coll]
  (map first (take-while realized? (iterate rest coll))))
但这仍然会产生一个无限的惰性序列,它使用
迭代

(defn take-realized [coll]
  (->> coll
       (iterate next)
       (take-while #(and % (or (not (instance? clojure.lang.IPending %)) (realized? %))))
       (map first)))

其他答案更为优越

是否要每次生成5个随机值的列表?“在不知道前五个值已经实现的情况下”你是什么意思?@Mark我不想每次都生成一个包含5个随机值的列表
infi-seq
延迟对其表达式的求值,直到需要它们为止。在本例中,计算五个表达式并缓存值。其余的
infi-seq
在需要时才进行评估。我想获得
infi-seq
的所有计算/缓存(实现)值。我希望这是一个可以接受的解释。是的,现在清楚了+1有时失败:
(实现[0 1 2 3 4])
产生
类CastException clojure.lang.PersistentVector$ChunkedSeq不能强制转换为clojure.lang.ipend
。分块中的一个缺陷?这里的
lazy seq
的目的是什么,因为它似乎在没有它的情况下工作?@Thumbnail可能
realized?
只接受延迟值?对,
realized?
只在ipend实例上工作。因此,
(以实现为例(iterate inc 1))
也会失败,因为
iterate
考虑到第一个元素没有
惰性序列
包装器。@deadghost我认为这是
实现?
中的一个缺陷,如果为承诺、延迟、未来或惰性序列生成了值,则据称返回true。考虑到,除了参数
clojure.lang.ipend
之外,它会爆炸。您是否必须在
seq
之前检查
clojure.lang.ipend
,因为
seq
可能有(并且在
iterate
的情况下,确实有)实现其参数的副作用?@Thumbnail Right,
seq
强制实现。如果没有实现可能的第一个元素,就无法检查惰性序列是否为空。是否需要进行
seq
测试?如果它实现了,它就有一个元素。丹尼的回答引发了这个想法。是的,这是必要的。不,实现的序列不一定有元素。终止的惰性序列以空尾终止<代码>(let[bar(doall(lazy-seq-nil)))((juxt-realized?empty?)bar));=>[正确]
(defn take-realized [coll]
  (map first (take-while realized? (iterate rest coll))))
(defn take-realized [coll]
  (->> coll
       (iterate next)
       (take-while #(and % (or (not (instance? clojure.lang.IPending %)) (realized? %))))
       (map first)))
(take 5 (take-realized (iterate inc 0)))
;(0 1 2 3 4)