未实现懒-seq的一步,我有一个懒序列,其中每个项目需要一定的时间来计算:我可以处理的步骤
(defn gen-lazy-seq [size]
(for [i (range size)]
(do
(Thread/sleep 1000)
(rand-int 10))))
是否有可能评估一步此序列步骤并打印结果。当我试着使用for
或doseq
Clojure的处理总是实现整体懒-seq的打印任何东西之前:
(doseq [item (gen-lazy-seq 10)]
(println item))
(for [item (gen-lazy-seq 10)]
(println item))
两个表达式将等待10秒打印任何东西之前。我曾将doall和dorun看作解决方案,但他们要求lazy-seq生成函数包含println。我想分别定义一个lazy-seq生成函数和lazy-seq打印函数,并使它们逐项地一起工作。
试图执行此操作的动机: 我有通过网络进入的消息,并且我希望在收到所有消息之前开始处理它们。同时,将所有对应于查询的消息保存在lazy-seq中将会很好。
编辑1:
JohnJ的回答显示了如何创建一个懒惰-seq的,将被评估一步一步来。我想知道如何逐步评估任何懒惰seq。
我很困惑,因为在上面定义的gen-lazy-seq上运行(chunked-seq? (gen-lazy-seq 10))
,或者如JohnJ的答案中定义的那样都返回false。那么问题不可能是一个创建了一个分块的序列,另一个没有。
在this答案中,显示了将分块lazy-seq变成非分块的函数的函数seq1。尝试该功能仍然会导致延迟输出的相同问题。我想,也许延迟已与某种在REPL缓冲要做,所以我试图同时打印时在SEQ每个项目实现时间:
(defn seq1 [s]
(lazy-seq
(when-let [[x] (seq s)]
(cons x (seq1 (rest s))))))
(let [start-time (java.lang.System/currentTimeMillis)]
(doseq [item (seq1 (gen-lazy-seq 10))]
(let [elapsed-time (- (java.lang.System/currentTimeMillis) start-time)]
(println "time: " elapsed-time "item: " item))))
; output:
time: 10002 item: 1
time: 10002 item: 8
time: 10003 item: 9
time: 10003 item: 1
time: 10003 item: 7
time: 10003 item: 2
time: 10004 item: 0
time: 10004 item: 3
time: 10004 item: 5
time: 10004 item: 0
与JohnJ的版本做同样的事GEN-懒-seq的作品如预期
; output:
time: 1002 item: 4
time: 2002 item: 1
time: 3002 item: 6
time: 4002 item: 8
time: 5002 item: 8
time: 6002 item: 4
time: 7002 item: 5
time: 8002 item: 6
time: 9003 item: 1
time: 10003 item: 4
编辑2:
这是与它有这个问题产生的不仅序列。地图生成该序列不能被处理步步无论SEQ1包装的:
(defn gen-lazy-seq [size]
(map (fn [_]
(Thread/sleep 1000)
(rand-int 10))
(range 0 size)))
但是该序列中,也与图创建的工作原理:
(defn gen-lazy-seq [size]
(map (fn [_]
(Thread/sleep 1000)
(rand-int 10))
(repeat size :ignored)))
我也试过'seq1',并没有设法使它与Clojure 1.5或1.2.1一起工作。这可能是因为你在实现'for'宏时遇到了一些特殊情况,这是一种透明的东西,你不能简单地通过将它封装在你自己的懒惰seq中来关闭它。 – JohnJ
感谢您的测试。这似乎是合理的问题是由于。我试图用地图创建一个lazy-seq,并按预期工作。 – snowape
再测试一下,似乎我和map生成的序列有同样的问题。 – snowape