在Clojure中,是否可以在匿名函数中定义匿名函数?

时间:2012-02-09 10:15:22

标签: clojure anonymous-function

例如,解决以下问题

http://projecteuler.net/problem=5

我提出了以下解决方案

(defn div [n] (= 0 (reduce + (map #(mod n %) (range 1 21)))))
(take 1 (filter #(= true (div %)) (range 20 1e11 20)))

假设某些高尔夫乐趣,我希望将第一行作为匿名函数合并到第二行。语言是否支持这个?

2 个答案:

答案 0 :(得分:17)

是的,但您无法嵌套#()阅读器 - 宏表单,您必须使用(fn)表单。

例如:

(#(#(+ %1 %2) 1) 2)

不起作用,因为没有办法引用外部匿名函数的参数。这被读作外部函数采用两个参数,内部函数采用零参数。

但你可以用(fn...) s写出相同的东西:

user=> (((fn [x] (fn [y] (+ x y))) 1) 2)
3

您还可以将#()表单用于两个匿名函数之一,例如:

user=> (#((fn [x] (+ x %)) 1) 2)
3

因此,您可以像这样内联div函数(请注意,我们必须将传递给#()的{​​{1}}表单更改为map表单):

(fn)

答案 1 :(得分:0)

您可以用更简单,更有效的方式重写解决方案(x2更快!)

(defn div [n] (every? #(= 0 (mod n %)) (range 1 21)))
(take 1 (filter div (range 20 1e11 20)))

它更有效的原因是因为every?不会遍历整个列表,而是在列表的某个元素为false时停止。