2013-03-14 60 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