6

私は基本的にClojuregoogleグループのディスカッションからヤンクした関数を持っています。これは、コレクションと任意の長さの関数のリストを取得し、それをフィルタリングして、元のリストのすべての要素を含む新しいコレクションを返します。関数の内、trueと評価されます。

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

私はプロジェクトオイラー問題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を渡すことができるように変更したいと思います。

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

ここで、3と5を任意の数のintに置き換え、multi-any-filter関数内で無名関数として(= 0(mod xy))の関数ラッピングを実行できます。

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

つまり、任意の数の引数(関数ではない)を渡して、それらの各引数を同じ関数でラップし、その関数のリストを私juxtの代わりに渡すことができるようにしたいのです。上記の機能。funcsmulti-any-filter

ヒントをありがとう!

4

1 に答える 1

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

partialの最初の位置にargが適用されるため、使用しませんfnevenly-divisible?再配置できる2番目の位置にしたいのですevenly-divisible?が、スタンドアロンで使用すると実際には正しく見えません。

user=> (reduce + (multi-any-filter (range 1 1000) 3 5))
233168
于 2013-03-14T20:39:16.677 に答える