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

del*_*ber 6 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)))
Run Code Online (Sandbox Code Playgroud)

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

liw*_*iwp 17

是的,但你不能嵌套#()阅读器宏表格,你必须使用(fn)表格.

例如:

(#(#(+ %1 %2) 1) 2)
Run Code Online (Sandbox Code Playgroud)

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

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

user=> (((fn [x] (fn [y] (+ x y))) 1) 2)
3
Run Code Online (Sandbox Code Playgroud)

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

user=> (#((fn [x] (+ x %)) 1) 2)
3
Run Code Online (Sandbox Code Playgroud)

所以,你可以你的内联div函数像这样(请注意,我们不得不改变#()传递到形式map(fn)形式):

#(= true (= 0 (reduce + (map (fn [x] (mod % x)) (range 1 21)))))
Run Code Online (Sandbox Code Playgroud)

  • 根据经验:`fn`是定义匿名函数的语法,而不是`#()`.`#()`只是简单函数调用的便利,例如`#(mod%x)`其中`fn`会增加很多噪音.对于具有较长主体的功能,应该首选`fn`. (7认同)