如何评估Clojure中的一系列不纯函数?

Ber*_*ler 11 clojure

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

[#(println "1") #(println "2") #(println "3")]
Run Code Online (Sandbox Code Playgroud)

预期的产出是:

1
2
3
Run Code Online (Sandbox Code Playgroud)

有没有办法在不使用宏的情况下实现这一目标?(map evaluate fns-seq)也许是这样的事情?

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

Bri*_*per 17

user> (let [fs [#(println "1") #(println "2") #(println "3")]]
         (doseq [f fs] (f)))
1
2
3
nil
Run Code Online (Sandbox Code Playgroud)


Mic*_*zyk 5

这将急切地消耗整个seq,调用副作用的所有函数并返回最后一个返回的内容:

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

如果要保留返回值,可以使用reductions:

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

reductions可以clojure.contrib.seq-utils在Clojure 1.1和clojure.core1.2的当前快照中找到.

更新:请注意,reductions返回一个懒惰的seq,所以它没有改进map(NB.map你想要使用#(%)而不是#(%2)).我在这里提到它主要是为了完整性.事实上,我发布了完整性的答案,因为通常我会采用这种doseq方法(参见Brian的回答).