Число? не может быть использован в спецификации
В Clojure 1.9.0-alpha13 я могу определить предикат спецификации, используя spec/and
а также integer?
но нет and
а также number?
, кажется. Это озадачивает. Также удивительно, что при определении предиката нет ошибки, а только когда я пытаюсь определить спецификацию, используя его.
user=> (use '[clojure.spec :as s])
...
nil
user=> (s/def pos-int? (s/and integer? pos?))
user/pos-int?
user=> (s/def ::foo pos-int?)
:user/foo
user=> (s/def pos-num? (s/and number? pos?))
user/pos-num?
user=> (s/def ::bar pos-num?)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: pos-num? ...
Почему я получаю ошибку во втором случае, а не в первом? Это особенность, о которой я не знаю, или ошибка?
Обратите внимание, что нет ошибки, если я определю ::bar
непосредственно:
user=> (s/def ::bar (s/and number? pos?))
:user/bar
2 ответа
Ваш код здесь неверный. s/def
должен вызываться с квалифицированным ключевым словом для регистрации спецификации, а не символа.
Итак, это:
user=> (s/def pos-int? (s/and integer? pos?))
user/pos-int?
не делает то, что вы думаете. Это на самом деле регистрация определения функции (что вы обычно делаете через s/fdef
) под символом user/pos-int?
,
user=> (s/def ::foo pos-int?)
:user/foo
Это работает, потому что pos-int?
это существующая функция в clojure.core (то есть она вообще не использует ваше предыдущее определение).
Это также, кажется, работает, но также неверно:
user=> (s/def pos-num? (s/and number? pos?))
user/pos-num?
Это не удается:
user=> (s/def ::bar pos-num?)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: pos-num? ...
потому что pos-num не является существующим предикатом.
Предполагая, что вы хотите зарегистрировать две спецификации для положительных целых чисел и чисел, которые вы можете сделать:
(s/def ::pos-int (s/and integer? pos?))
(s/def ::pos-num (s/and number? pos?))
Я считаю, что вы обнаружили взаимодействие с предопределенным pos-int?
от clojure.core
, В исходном коде:
src / clj / clojure / core.clj строка 1400
(defn pos-int?
"Return true if x is a positive fixed precision integer"
{:added "1.9"}
[x] (and (int? x)
(pos? x)))
Здесь нет pos-num?
подарок.