# Every-pred for functions with multiple arguments

`every-pred` is great and it works nicely for functions that take a single argument. e.g.:

``````((every-pred string? #(< 5 (count %))) "lengthy") => true
``````

But I wanted to make it work with functions that take more than one argument and something like this, doesn’t seem to work:

``````((every-pred (fn [a b]
(and (number? a)
(number? b)))
(fn [a b]
(< a b)))
1 2)
``````

That throws an `ArityException`. I checked, the inner expression definitely retuns a function that takes two arguments. So why it doesn’t work then?

For archival, going to repeat my answer from the slack here as well:

`every-pred` only works with predicate functions of one argument, but to make it work with predicate functions of two or more args, you could simply wrap your predicate functions in a function of one argument.

For example, you could convert your preds of two args, into preds of one arg which take a vector of two elements:

``````((every-pred (fn [[a b]]
(and (number? a)
(number? b)))
(fn [[a b]]
(< a b)))
[1 2])
``````

You can generalize this using apply as well:

``````;; Assume we have pred-x and pred-y, both take two args, and we
;; don't have control on them, so we can't change their definition, we
;; can use apply and anonymous functions instead:

(defn pred-x [a b]
(= a b))

(defn pred-y [a b]
(and (> 10 a)
(> 10 b)))

((every-pred
#(apply pred-x %)
#(apply pred-y %))
[5 5])
true

;; We can now make an even more generic function for this pattern:

(defn every-preds [& preds]
(fn [& args]
((apply every-pred
(mapv
(fn [p]
(fn [args]
(apply p args)))
preds))
args)))

((every-preds pred-x pred-y) 5 5)
true
``````
3 Likes

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.