Как определить спецификацию Clojure для `'(foo (: x 1: y 2))` - PullRequest
0 голосов
/ 23 октября 2018

The:

(s/def ::a (s/cat :k keyword? :i int?))
(s/def ::b (s/cat :symbol any?
                  :a      (s/coll-of ::a)))

характеристики: (s/conform ::b '(foo ((:x 1) (:y 2))))

The:

(s/def ::a (s/cat :k keyword? :i int?))
(s/def ::b (s/cat :symbol any?
                  :a      (s/* ::a)))

характеристики: (s/conform ::b '(foo :x 1 :y 2))

но как сделатьЯ спец (s/conform ::b '(foo (:x 1 :y 2)))?

1 Ответ

0 голосов
/ 23 октября 2018

Чтобы вложить это в список, вам нужно обернуть его в s/spec.Например:

(s/def ::b (s/cat :symbol any? :a (s/spec (s/* ::a))))

Это упоминается в Руководстве по спецификациям :

Когда операции регулярных выражений объединяются, они описывают одну последовательность.Если вам нужно указать вложенную последовательную коллекцию, вы должны использовать явный вызов spec для запуска нового вложенного контекста регулярного выражения.Например, чтобы описать последовательность вроде [: names ["a" "b"]: nums [1 2 3]], вам нужны вложенные регулярные выражения для описания внутренних последовательных данных:

 (s/def ::nested
   (s/cat :names-kw #{:names}
          :names (s/spec (s/* string?))
          :nums-kw #{:nums}
          :nums (s/spec (s/* number?))))
 (s/conform ::nested [:names ["a" "b"] :nums [1 2 3]])
 ;;=> {:names-kw :names, :names ["a" "b"], :nums-kw :nums, :nums [1 2 3]}
...