执行一系列懒惰的函数

时间:2014-02-20 18:00:42

标签: clojure lazy-sequences

我想知道如何强制评估一系列惰性函数。

例如,如果我有一个返回整数1的函数:

test.core=> (fn [] 1)
#<core$eval2480$fn__2481 test.core$eval2480$fn__2481@4163c61>
test.core=> ((fn [] 1))
1

我构建了这些函数的惰性序列:

test.core=> (repeat 5 (fn [] 1))
(#<core$eval2488$fn__2489 test.core$eval2488$fn__2489@76fd6301> ...)

test.core=> (class (repeat 5 '(fn [] 1)))
clojure.lang.LazySeq

如何实际执行序列中的功能?

test.core=> (take 1 (repeat 5 (fn [] 1)))
(#<core$eval2492$fn__2493 test.core$eval2492$fn__2493@46e1e0c8>)

test.core=> (take 1 (repeat 5 '(fn [] 1)))
((fn [] 1))

test.core=> ((take 1 (repeat 5 '(fn [] 1))))

ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.IFn

我已经阅读了How to convert lazy sequence to non-lazy in Clojure,其中提出了doall ......但我不确定结果会在哪里发生?我期待[1 1 1 1 1]或类似的东西。

test.core=> (doall (repeat 5 (fn [] 1)))
(#<core$eval2500$fn__2501 test.core$eval2500$fn__2501@14e3c50c>...)

test.core=> (realized? (doall (repeat 5 (fn [] 1))))
true

1 个答案:

答案 0 :(得分:3)

您的问题是您正在返回一系列未评估的函数。您可以按如下方式评估它们:

=> (map #(%) (repeat 5 (fn [] 1)))
(1 1 1 1 1)

maprepeat都是懒惰的,但REPL或任何其他消费者强制评估至少与其需要的懒惰序列一样多。