количество? нельзя использовать в спецификации

В 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

person Mars    schedule 27.10.2016    source источник


Ответы (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?))
person Alex Miller    schedule 27.10.2016
comment
О, большое спасибо за прояснение моего многогранного замешательства. - person Mars; 28.10.2016

Я полагаю, вы обнаружили взаимодействие с предопределенным 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? отсутствует.

person Alan Thompson    schedule 27.10.2016
comment
Кроме того, вы можете опубликовать этот вопрос в списке адресов электронной почты группы Clojure google, чтобы получить более подробное объяснение. - person Alan Thompson; 27.10.2016