2013-03-14 8 views
6

Ich habe eine Funktion, die ich im Grunde aus einer Diskussion in der Clojure Google-Gruppe gezogen, die eine Sammlung und eine Liste von Funktionen beliebiger Länge, und filtert es, um eine neue Sammlung mit allen Elementen der ursprünglichen Liste für die zurückgegeben an mindestens eine der Funktionen wahr ausgewertet:Clojure Partial Application - Wie bekomme ich 'map', um eine Sammlung von Funktionen zurückzugeben?

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

ich spiele um eine verallgemeinerungsfähige Lösung Project Euler Problem 1 mit der Herstellung, so dass ich es wie folgt mit:

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

Welche die richtige Antwort gibt .

Allerdings mag ich es so modifizieren, ich ints es anstelle von Funktionen, wie

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

passieren kann, wo ich 3 und 5 mit einer beliebigen Anzahl von Ints ersetzen kann und tun, um die Funktion Verpackung von (= 0 (mod xy)) als anonyme Funktion innerhalb der Multi-Any-Filter-Funktion.

Leider ist das die Grenze meiner Clojure Fähigkeit überschritten. Ich denke, dass ich etwas mit map zu der Liste von Argumenten tun müsste, aber ich bin nicht sicher, wie man map erhält, um eine Liste von Funktionen zurückzugeben, von denen jedes auf ein anderes Argument wartet. Clojure scheint Curry nicht zu unterstützen, wie ich es in anderen funktionalen Sprachen gelernt habe. Vielleicht muss ich partial an der richtigen Stelle verwenden, aber ich bin mir nicht ganz sicher, wie.

Mit anderen Worten, ich möchte in der Lage sein, eine beliebige Anzahl von Argumenten (die keine Funktionen sind) übergeben und dann diese Argumente in die gleiche Funktion gewickelt werden, und dann diese Liste der Funktionen an juxt übergeben wird anstelle von funcs in meiner multi-any-filter Funktion oben.

Danke für irgendwelche Tipps!

Antwort

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 ich partial verwenden, weil es die arg in der ersten Position der fn gilt. Wir wollen es in der zweiten Position von evenly-divisible? Wir könnten in evenly-divisible? neu anordnen, aber dann würde es nicht wirklich richtig aussehen, wenn Sie es eigenständig verwenden.

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

Sie rocken, das ist genau das, was ich gesucht habe. – kyllo