在Clojure中,是否可以在匿名函数中定义匿名函数?
例如,解决以下问题 我提出了以下解决方案在Clojure中,是否可以在匿名函数中定义匿名函数?,clojure,anonymous-function,Clojure,Anonymous Function,例如,解决以下问题 我提出了以下解决方案 (defn div [n] (= 0 (reduce + (map #(mod n %) (range 1 21))))) (take 1 (filter #(= true (div %)) (range 20 1e11 20))) 假设为了好玩,我想把第一行作为匿名函数合并到第二行。该语言是否支持此功能?是的,但不能嵌套#()读取器宏窗体,必须使用(fn)窗体 例如: (#(#(+ %1 %2) 1) 2) 不起作用,因为无法引用外部匿名函数的参
(defn div [n] (= 0 (reduce + (map #(mod n %) (range 1 21)))))
(take 1 (filter #(= true (div %)) (range 20 1e11 20)))
假设为了好玩,我想把第一行作为匿名函数合并到第二行。该语言是否支持此功能?是的,但不能嵌套
#()
读取器宏窗体,必须使用(fn)
窗体
例如:
(#(#(+ %1 %2) 1) 2)
不起作用,因为无法引用外部匿名函数的参数。这被理解为外部函数具有两个参数,内部函数具有零个参数
但是你可以用(fn…
s写同样的东西:
您还可以将#()
表单用于两个匿名函数之一,例如:
user=> (#((fn [x] (+ x %)) 1) 2)
3
因此,您可以像这样内联div
函数(注意,我们必须将传递到map
的#()
表单更改为(fn)
表单):
您可以用一种更简单、更高效的方式重写您的解决方案(x2更快!)
它之所以更有效,是因为
every?
不会遍历整个列表,而是在列表的一个元素为false时停止 根据经验:fn
是定义匿名函数的语法,而不是#()
#()
只为简单的函数调用提供了方便,如#(mod%x)
,其中fn
会增加很多噪音。对于主体较长的函数,应首选fn
。您可以更有效地重写解决方案。请看下面我的答案。或者你可以在10点左右解决它⁶ 通过完全避免暴力,速度会快很多。的确但我正在考虑任何与clojure相关的改进,而不是数学上的改进。
user=> (#((fn [x] (+ x %)) 1) 2)
3
#(= true (= 0 (reduce + (map (fn [x] (mod % x)) (range 1 21)))))
(defn div [n] (every? #(= 0 (mod n %)) (range 1 21)))
(take 1 (filter div (range 20 1e11 20)))