如何在Clojure

时间:2015-08-10 21:16:12

标签: clojure lisp

我的问题非常类似于这个问题:How to evaluate a sequence of impure functions in Clojure?但是我如何评估纯函数的序列并将结果作为另一个序列来代替不纯函数?

假设我们有一个函数向量,如:

[#(str "a" "b") #(str "c" "d") #(str "e" "f")]

我们需要这样的输出:

("ab" "cd" "ef")

我尝试过类似的东西:

(map eval [#(str "a" "b") #(str "c" "d") #(str "e" "f")])

但它只返回一个函数引用向量。

5 个答案:

答案 0 :(得分:9)

有多种方法可以满足您的要求。这取决于你是否想要一个懒惰的序列(你可能想要懒惰,因为没有副作用,但如果你想要一个密集的计算,你可能想要没有懒惰缓存),或者你想要一个矢量作为输出(与你的输入相同)。我会尝试按照您的尝试去做。

您的带有eval的地图正在对每个fn执行以下操作:

user=> (eval #(str 1))
#<user$eval1332$fn__1333 user$eval1332$fn__1333@38747597>

但是你需要以下内容:

user=> (eval (#(str 1)))
"1"

您希望eval应用fn,即:fn应该是列表的第一个元素。让我们把它放在一个列表中:

user=> (map (comp eval list) [#(str "a" "b") #(str "c" "d") #(str "e" "f")])
("ab" "cd" "ef")

冷却。但是,您可能希望使用apply:

而不是eval
user=> (apply #(str 1))
; ArityException Wrong number of args (1)

盛衰!它失败了。 apply没有0-arity重载,但我们可以传递一个空列表:

user=> (apply #(str 1) ())
"1"

好多了。让我们用map:

来做
user=> (map #(apply % ()) [#(str "a" "b") #(str "c" "d") #(str "e" "f")])
("ab" "cd" "ef")

或者更好的是,鉴于你的职能没有得到任何论据,你最好按照@Magos的建议去做:

user=> (map #(%) [#(str "a" "b") #(str "c" "d") #(str "e" "f")])                                                                              
("ab" "cd" "ef")

答案 1 :(得分:5)

您可以在(fn [f] (f))中使用#(%)map

答案 2 :(得分:1)

void init() { ... engine = new GameEngine(); gui = new GUI(); gui.setActionListener(engine); ... } 评估Clojure表单(即包含&#34;代码&#34;的列表)。你有功能,而不是形式。

eval map apply,但apply同时接受函数和seq个参数。由于您没有参数,因此可以使用空向量:

(map apply
     [#(str "a" "b") #(str "c" "d") #(str "e" "f")]
     (repeat []))

但如果使用for

,它会更短,可能更清晰
(for [f [#(str "a" "b") #(str "c" "d") #(str "e" "f")]]
  (f))

答案 3 :(得分:1)

注意

作为Nathan Davis wrote$_GET['id']评估clojure 表单

eval

它对一个功能有什么作用? 没什么!的。 (eval '(+ 1 1)) ;=> 2 将函数视为文字:

eval

对于你的情况:

((eval +) 1 1) ;=> 2

......我们有

(def stuff [#(str "a" "b") #(str "c" "d") #(str "e" "f")])

虽然

(= stuff (map eval stuff)) ;=> true

...因为相应的功能是不同的对象,尽管操作相同。

这就是(= [#(str "a" "b") #(str "c" "d") #(str "e" "f")] (map eval [#(str "a" "b") #(str "c" "d") #(str "e" "f")])) ;=> false 对你没用的原因。请按照Magos's advice进行操作。

答案 4 :(得分:0)

或许有必要查看pcalls和/或pvalues

(pcalls #(str "a" "b") #(str "c" "d") #(str "e" "f"))
;=> ("ab" "cd" "ef")

请注意,pcalls正在使用future