2009-07-30 7 views

Respuesta

9

Usted podría utilizar every?:

user=> (every? string? '("hi" 1)) 
false 

Aquí está la documentación sobre every?.

1

every? preguntará "¿Esta función única devuelve verdadera para cada miembro del seq", que es cercana a lo que creo que está solicitando. Una mejora en every? tomaría una lista de funciones y preguntaría "Son todos estos predicados verdaderos para cada miembro de esta secuencia".

Aquí es un primer intento:

(defn andmap? [data tests] 
    (every? true? (for [d data, f tests] 
        (f d)))) 

user> (andmap? '(2 4 8) [even? pos?]) 
true 
user> (andmap? '(2 4 8) [even? odd?]) 
false 
1

escribí andmap como una macro que tiene predicados como sus argumentos y construye una función que "envuelve una and alrededor de los predicados", es decir,

(andmap integer? odd?) 
==> 
(fn [x] (and (integer? x) 
      (odd? x))) 

(no se expande a exactamente esto, pero se expande a algo equivalente a esto)

Esto tiene la ventaja de que shortcuircuts en los predicados para que pueda escribir

(every? (andmap integer? odd?) [1 3 "a string"]) 

sin obtener una excepción de tiempo de ejecución que se tendría con Arthurs answer.

Aquí es la definición de andmap:

 
(defmacro andmap 
    ([]  `(fn [& x#] true)) 
    ([p & ps] `(fn [& x#] (and (apply ~p x#) 
          (apply (andmap [email protected]) x#))))) 

También es posible definir andmap como una función que también cortocircuitos en él es predicados debido a la pereza:

 
(defn andmap [& ps] 
    (fn [& x] 
    (every? true? (map (fn [p] (apply p x)) ps)))) 

Los predicados a andmap puede tomar una cantidad arbitraria de argumentos, por lo que es posible escribir

(map (andmap #(and (integer? %1) 
        (integer? %2)) 
      #(and (odd? %1) 
        (even? %2)) 
      <) 
    [1 3 9] 
    [2 6 "string"]) 

que evalúa a (true true false).

2

Clojure 1.3 agregará every-pred (y el relacionado con algunos-fn para la versión "o").

clojure.core/cada-pred ([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps])

toma un conjunto de predicados y devuelve una función f que devuelve verdadero si todos sus predicados de composición devuelven un valor verdadero lógico contra todos sus argumentos, de lo contrario devuelve falso. Tenga en cuenta que f está cortocircuitándose en el sentido de que detendrá la ejecución en el primer argumento que desencadena un falso resultado lógico contra los predicados originales.

Una implementación ingenua podría ser:

(defn cada-pred [& Preds] (fn [& args] (cada # (cada% args) Preds))??)

pero el reales la implementación tendrá un mejor rendimiento.

Cuestiones relacionadas