2010-06-21 35 views
11

如何评估Clojure中的(不纯)函数列表?例如:如何评估Clojure中不纯功能的序列?

[#(println "1") #(println "2") #(println "3")] 

预期输出是:

1 
2 
3 

有没有办法实现这一目标而无需使用宏?像(map evaluate fns-seq),也许?

(我需要这个使用Clojure.processing API绘制一些图形。)

回答

17
user> (let [fs [#(println "1") #(println "2") #(println "3")]] 
     (doseq [f fs] (f))) 
1 
2 
3 
nil 
+0

大,即工作。非常感谢! – 2010-06-22 20:00:00

5

这将热切消耗全部SEQ,呼吁副作用的所有功能,并返回无论最后一个返回:

(reduce #(%2) nil [#(println :foo) #(println :bar)]) 
; => prints :foo, then :bar, then returns nil 

如果你想守住返回值,你可以使用reductions代替:

(reductions #(%2) nil [#(println :foo) #(println :bar)]) 
; => prints :foo, then :bar, then returns (nil nil) 

reductions在Clojure 1.1和clojure.core中的clojure.contrib.seq-utils中找到1.2的当前快照。

更新:注意reductions返回一个懒惰的序列,因此它在map没有改善(特别注意:在map你想使用#(%)而非#(%2))。我在这里提到它主要是为了完整性。事实上,我发布了完整答案,因为通常我会采用doseq方法(请参阅Brian的答案)。

+0

感谢您的额外评论。我可以想象,当处理来自命令性Java世界的图书馆时,我的“问题”会更频繁地出现。也许一个宏(dofns fns)会是一个很好的抽象,这在Clojure中目前是缺少的。 – 2010-06-22 20:05:02

1

(apply pcalls [#(println "1") #(println "2") #(println "3")])就是这样做的。请谨慎对待pcalls'并行性(因此缺乏顺序性)和懒惰。

+0

很高兴知道pcalls :) – nXqd 2016-03-28 09:33:18

0

我知道一个老问题,但还有另一种选择。 你可以简单地invoke功能:

(defn generate-fns [] 
    [#(println "1") #(println "2") #(println "3")]) 

(dorun (pmap (memfn invoke) (generate-fns))) 

这使您可以在不同的上下文决定你希望如何执行功能(比如,pmap,或claypoole'supmap例如)