Как вы составляете два или более предикатов в clojure?

Я хочу применить два (или более) предиката к одному значению. Например, скажем, я хочу проверить, является ли значение положительным целым числом:

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

Это делает, но что делать, если я хочу составить предикаты? Я не хочу писать функцию для каждой возможной комбинации предикатов.

Ответы

Ответ 1

В Clojure 1.3 на самом деле есть встроенная функция every-pred, чтобы сделать это. См. здесь.

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

Ответ 2

Если вы хотите сделать эти проверки в строгом соответствии, вы можете найти следующее.

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

Затем вы можете создать именованные версии для наиболее часто используемых тестов предикатов:

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

(posint? 4)

Ответ 3

Если вы хотите объединить их в отношения and, используйте every-pred:

((every-pred pos? even?) 5)
;false
((every-pred pos? even?) 6)
;true
((every-pred pos? even?) -2)
;false

И если вы хотите объединить их в отношения or, используйте some-fn:

((some-fn pos? even?) 5)
;true
((some-fn pos? even?) 6)
;true
((some-fn pos? even?) -2)
;true
((some-fn pos? even?) -3)
;false