I have many predicate functions in a vector fs, and would like to and them all together. This works for the first two functions:
((and (first fs) (second fs)) value)
However I would like to write code that applies and to all the functions, no matter how many there are. (apply and fs) does not compile because and is a macro.
For an example of predicate functions working with and, try this:
((and number? integer?) 1)
Edit In case you don't read the comments, both and constructions above are BAD EXAMPLES. For same constructions to actually work use every-pred rather than and.
Since you are working with predicates, every-pred may be of interest.
After reading your edit - thanks, I didn't know and you could do that with and. Additionally I've edited my answer, and I think you definitely want to apply every-pred
((apply every-pred [number? integer?]) 1)
=> true
((apply every-pred [number? integer?]) "asdf")
=> false
It looks like every-pred is a good answer to this question (I hadn't noticed it before!). A related function that may be handy is juxt. It applies a number of functions to a single argument:
((juxt a b c) x) => [(a x) (b x) (c x)]
Note that, unlike every-pred, the juxt function does not short-circuit and always evaluates each function in the list. An example:
(ns tst.clj.core
(:use clj.core clojure.test tupelo.test)
(:require [tupelo.core :as t] ))
(defn f2 [x] (zero? (mod x 2)))
(defn f3 [x] (zero? (mod x 3)))
(defn f5 [x] (zero? (mod x 5)))
(def f235 (apply juxt [f2 f3 f5] ))
This gives us results:
(f235 2) => [true false false]
(f235 3) => [false true false]
(f235 5) => [false false true]
(f235 6) => [true true false]
(f235 10) => [true false true]
(f235 15) => [false true true]
(f235 30) => [true true true]
(every? truthy? (f235 15)) => false
(every? truthy? (f235 30)) => true
where the truthy? function is similar to boolean:
(defn truthy?
"Returns true if arg is logical true (neither nil nor false); otherwise returns false."
[arg]
(if arg true false))
P.S. Please note that your original example does not say (and (f1 x) (f2 x)) but instead says (and f1 f2) => f1. So when you type
(def fs [f1 f2 f3 f4])
((and (first fs) (second fs)) value)
=> ((and f1 f2) value)
=> (f1 value)
which does not give the result you were seeking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With