Clojure Partial Application - How to get 'map' to return a collection of functions?

clojure, higher-order-functions, partial-application

Solution

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

I coudn't use `partial` because it applies the arg in the first position of the `fn`. We want it in the second position of `evenly-divisible?` We could re-arrange in `evenly-divisible?` but then it would not really look correct when using it standalone.

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

Problem

I have a function that I basically yanked from a discussion in the Clojure google group, that takes a collection and a list of functions of arbitrary length, and filters it to return a new collection containing all elements of the original list for which at least one of the functions evaluates to true: ``` (defn multi-any-filter [coll & funcs] (filter #(some true? ((apply juxt funcs) %)) coll)) ``` I'm playing around with making a generalizable solution to Project Euler Problem 1, so I'm using it like this: ``` (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)) ``` Which gives the correct answer. However, I want to modify it so I can pass ints to it instead of functions, like ``` (reduce + (multi-any-filter (range 1 1000) 3 5)) ``` where I can replace 3 and 5 with an arbitrary number of ints and do the function wrapping of (=0 (mod x y)) as an anonymous function inside the multi-any-filter function. Unfortunately this is past the limit of my Clojure ability. I'm thinking that I would need to do something with `map` to the list of args, but I'm not sure how to get `map` to return a list of functions, each of which is waiting for another argument. Clojure doesn't seem to support currying the way I learned how to do it in other functional languages. Perhaps I need to use `partial` in the right spot, but I'm not quite sure how. In other words, I want to be able to pass an arbitrary number of arguments (that are not functions) and then have each of those arguments get wrapped in the same function, and then that list of functions gets passed to `juxt` in place of `funcs` in my `multi-any-filter` function above. Thanks for any tips!

Original source