La función number?
suena como lo que necesita. Tal vez una prueba de (and (number? arg1) (number? arg2))
.
Hace un tiempo, Brian Carper sugirió una serie de macros y de funciones para usar en la validación de los diferentes tipos de argumentos numéricos:
;; Suggested by Brian Carper at:
;;http://stackoverflow.com/questions/1640311/should-i-use-a-function-or-a-macro-to-validate-arguments-in-clojure
(defmacro assert* [val test]
`(let [result# ~test]
(when (not result#)
(throw (IllegalArgumentException.
(str "Test failed: " (quote ~test)
" for " (quote ~val) " = " ~val))))))
(defmulti validate* (fn [val test] test))
(defmethod validate* :prob [x _]
(assert* x (and (number? x) (pos? x) (<= x 1.0))))
(defmethod validate* :posint [x _]
(assert* x (and (integer? x) (pos? x))))
(defmethod validate* :non-negint [x _]
(assert* x (and (integer? x) (not (neg? x)))))
(defmethod validate* :posnum [x _]
(assert* x (and (number? x) (pos? x))))
(defmethod validate* :percentage [x _]
(assert* x (and (number? x) (pos? x) (<= x 100))))
(defmethod validate* :numseq [x _]
(assert* x (and (not (empty? x)) (seq? x) (every? number? x))))
(defmethod validate* :nonzero-numseq [x _]
(assert* x (and (not (empty? x)) (seq? x) (every? #(and (number? %) (not (zero? %))) x))))
(defmethod validate* :posint-seq [x _]
(assert* x (and (not (empty? x)) (seq? x) (every? #(and (integer? %) (pos? %)) x))))
(defmethod validate* :prob-seq [x _]
(assert* x (and (not (empty? x)) (seq? x) (every? #(and (number? %) (pos? %) (<= % 1.0)) x))))
(defmethod validate* :default [x _]
(throw (IllegalArgumentException.
(str "Unrecognized validation type"))))
(defn validate [& tests]
(doseq [test tests] (apply validate* test)))
Esto ha demostrado ser muy flexible en mi experiencia. Como puede ver, es fácil extender el mulitmethod a nuevas pruebas.
uso sería algo así como:
(defn f [arg1 arg2]
"arg1 must be a positive integer, arg2 must be a positive number"
(validate [arg1 :posint] [arg2 :posnum])
...
)
Gracias, Justin. ¿Sería una mala forma para mí no usar ': pre' y usar algo más en su lugar? Me encuentro en una situación en la que es un poco difícil (aunque creo que tu respuesta es probablemente la que la mayoría de la gente querrá). – charleslparker
No se puede emitir un juicio sin más detalles. ¿Por qué es difícil usar ': pre'? –