2011-10-27 8 views
14

Quiero aplicar dos (o más) predicados a un solo valor. Por ejemplo, digamos que quiero probar si un valor es un entero positivo:¿Cómo se componen dos o más predicados en clojure?

(defn posint? [n] 
    (and (integer? n) (pos? n))) 

que lo hace, pero lo que si quiero componer los predicados aplicados? No quiero escribir una función para cada posible combinación de predicados.

Respuesta

20

En Clojure 1.3 en realidad hay una función integrada llamada every-pred para hacer precisamente esto. Ver here.

(defn posint? [n] 
    ((every-pred integer? pos?) n)) 
+0

Este incluso maneja '(posint?" A ")'! Necesito una solución 1.2 aunque desafortunadamente. – stand

+2

@stand: creo que puede tomar esta función de las fuentes de Clojure y ponerla en su código –

2

Si está buscando hacer estos controles en línea, lo siguiente puede ser lo que está buscando.

(defn predicate-test [fns t] 
    "test all predicates against value t and return true iff all predicates return true." 
    (every? true? ((apply juxt fns) t))) 

(predicate-test [integer? pos?] 4) 

A continuación, puede crear versiones llevan el nombre de sus pruebas de predicados más utilizados:

(def posint? (partial predicate-test [integer? pos?]) 

(posint? 4) 
+0

Ah sí, era la función 'juxt' que me faltaba. ¡Gracias! – stand

+0

... aunque esta solución arroja una excepción cuando haces un '(posint?" A ")' ya que 'pos?' Lanza una 'CastException'. No puedo pensar en una forma de cortocircuitar la forma en que 'y' lo hace. – stand

Cuestiones relacionadas