2014-02-20 60 views
0

我在想如何強制一個懶惰的函數序列進行評估。執行一個懶惰的函數序列

舉例來說,如果我有一個返回整數1功能:

test.core=> (fn [] 1) 
#<core$eval2480$fn__2481 [email protected]> 
test.core=> ((fn [] 1)) 
1 

我構建這些功能的懶惰序列:

test.core=> (repeat 5 (fn [] 1)) 
(#<core$eval2488$fn__2489 [email protected]> ...) 

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

我怎麼竟在執行功能序列?

test.core=> (take 1 (repeat 5 (fn [] 1))) 
(#<core$eval2492$fn__2493 [email protected]>) 

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 [email protected]>...) 

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

回答

3

你的問題是你正在返回一系列未評估函數。

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

兩個maprepeat懶惰,但REPL或任何其他消費迫使至少不亞於它需要一個懶序列的評價:可以按如下方式對其進行評估。

+1

而且值得注意的是,序列分塊會導致它們以塊爲單位進行評估。12 –

+1

僅適用於產生分塊序列的函數(「重複」不)。分塊問題偶爾會發生,但在OP計算出如何調用函數列表之後很長時間內可以忽略它。 – amalloy