Как распаковать спецификацию последовательности?

с Clojure core.spec у меня может быть следующее:

(s/conform (s/cat :a even? :b (s/* odd?) :a2 even? :b2 (s/* odd?))  [2 3 5 12 13 15])
=> {:a 2, :b [3 5], :a2 12, :b2 [13 15]}

то, что я хотел бы иметь, это удалить избыточность, вынеся вспомогательную спецификацию:

(s/def ::even-followed-by-odds 
  (s/cat :a even? :b (s/* odd?)))

но

(s/conform (s/tuple ::even-followed-by-odds ::even-followed-by-odds)  [2 3 5 12 13 15])
=> :clojure.spec/invalid

этот работает:

(s/conform (s/tuple ::even-followed-by-odds ::even-followed-by-odds)  [[2 3 5] [12 13 15]])
=> [{:a 2, :b [3 5]} {:a 12, :b [13 15]}]

Итак, я ищу функцию или макрос (скажем, unnest), который заставит его работать:

(s/conform (s/tuple (unnest ::even-followed-by-odds) (unnest ::even-followed-by-odds))  [2 3 5 12 13 15])
=> [{:a 2, :b [3 5]} {:a 12, :b [13 15]}]

как я могу это получить?


person Lambder    schedule 20.04.2017    source источник


Ответы (1)


Вам нужно оставаться в регулярном выражении:

(s/conform (s/cat :x ::even-followed-by-odds :y ::even-followed-by-odds) [2 3 5 12 13 15])

{:x {:a 2, :b [3 5]}, :y {:a 12, :b [13 15]}}
person Alex Miller    schedule 20.04.2017
comment
большое спасибо @alex-miller за очень быстрый ответ. - person Lambder; 21.04.2017