2013-03-14 9 views
6

私は、Clojure googleグループの議論から、基本的には、コレクションと任意の長さの関数のリストを取り、それをフィルタリングして元のリストのすべての要素を含む新しいコレクションを返すようにフィルタリングしています機能の少なくとも一つが真と評価:Clojure部分アプリケーション - 関数のコレクションを返すための 'map'の取得方法?

(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)) 

しかし、私はint型の任意の数を3と5を交換し、機能の折り返しを行うことができますどこで(

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

のように、機能するのではなく、それにint型を渡すことができますので、それを変更したいです= 0(mod xy))を複数のany-filter関数の中の無名関数として扱います。

残念ながら、これは私のClojure能力の限界を超えています。私はargsのリストにmapで何かする必要があると思っていますが、私はmapがそれぞれ別の引数を待っている関数のリストを返す方法を知りません。 Clojureは、私が他の関数型言語でそれを行う方法を学んだやりかたをカリングするのをサポートしていないようです。おそらく私は正しい場所にpartialを使用する必要がありますが、私はどのようにはっきりしていません。

つまり、(関数ではない)任意の数の引数を渡して、それらの引数のそれぞれを同じ関数にラップさせたい場合、その関数のリストはjuxtに渡されます。上記の私のmulti-any-filter機能でfuncsの代わりに。

ありがとうございました!

答えて

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))) 

私はそれがfnの最初の位置に引数を適用するためpartialを使用coudn't。 evenly-divisible?の2番目の位置にしたいevenly-divisible?に再配置することができますが、スタンドアロンで使用すると正しく表示されません。

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

これはまさに私が探していたものです。 – kyllo

関連する問題