2013-03-14 61 views
6

我有一个函数,我基本上从Clojure谷歌组中讨论了一个函数,该函数需要一个集合和一个任意长度的函数列表,并对它进行过滤,以返回一个包含原始列表的所有元素的新集合,功能至少一个计算为真:Clojure部分应用 - 如何让'地图'返回一组函数?

(defn multi-any-filter [coll & funcs] 
    (filter #(some true? ((apply juxt funcs) %)) coll)) 

我玩弄作出概括性解决Project Euler Problem 1,所以我用这样的:

(def f3 (fn [x] (= 0 (mod x 3)))) 
(def f5 (fn [x] (= 0 (mod x 5)))) 

(reduce + (multi-any-filter (range 1 1000) f3 f5)) 

其中给出了正确的答案。

然而,我想修改它,所以我可以通过整数到它,而不是功能,如

(reduce + (multi-any-filter (range 1 1000) 3 5)) 

在哪里可以与整数的任意数量的取代3,5与做的功能包裹( = 0(mod xy))作为multi-any-filter函数中的匿名函数。

不幸的是,这已经超过了我的Clojure能力的极限。我在想,我需要用map来做一些参数列表,但我不知道如何让map返回一个函数列表,每个函数都在等待另一个参数。 Clojure似乎并不支持我学习如何在其他函数式语言中使用它的方式。也许我需要在正确的位置使用partial,但我不太确定。

换句话说,我希望能够传递任意数量的参数(不是函数),然后让这些参数中的每一个都被包装在同一个函数中,然后该函数列表被传递给juxt代替funcs在我的multi-any-filter函数上面。

感谢您的任何提示!

回答

6
(defn evenly-divisible? [x y] 
    (zero? (mod x y))) 

(defn multi-any-filter [col & nums] 
    (let [partials (map #(fn [x] (evenly-divisible? x %)) nums) 
     f (apply juxt partials)] 
    (filter #(some true? (f %)) col))) 

我coudn't使用partial,因为它在fn的第一位置应用ARG。我们希望它在evenly-divisible?的第二位,我们可以在evenly-divisible?中重新排列,但是当它独立使用时,它看起来并不正确。

user=> (reduce + (multi-any-filter (range 1 1000) 3 5)) 
233168 
+0

你摇滚,这正是我一直在寻找的东西。 – kyllo 2013-03-14 22:06:39