Как написать спецификацию Clojure для функции, которая принимает аргумент последовательности? - PullRequest
0 голосов
/ 11 сентября 2018

Я пишу функцию, которая принимает последовательность треугольников (которые на самом деле представлены как maps).

Моя спецификация:

(s/fdef triangle-list-to-pattern
        :args (s/cat :trs (s/* ::maths/Triangle))
        )

И функция принимаетодин аргумент, trs, который представляет собой последовательность треугольников.

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

fails spec: :patterning.maths/Triangle at: [:args :trs] predicate: map?

Если я явно проверю аргумент I,перехожу к функции со спец.Это на самом деле просто последовательность вещей, которые соответствуют критериям треугольника.

Функция, кажется, работает.Аргумент кажется правильным и проходит спецификацию при тестировании отдельно.Итак, я предполагаю, что я как-то ошибаюсь в fdef.

В чем проблема?

Примечание, :: Треугольник определен:

(s/def ::Triangle (s/keys :req-un [::A ::B ::C ::a ::b ::c ::ax ::ay ::bx ::by ::cx ::cy]))

1 Ответ

0 голосов
/ 11 сентября 2018

Причина, по которой ваша :args спецификация не работает, состоит в том, что regex specs составляют для описания одной последовательности при вложении.

Вы можете избежать этого поведения, добавив внутреннюю спецификацию регулярного выражения s/* в s/spec:

(s/cat :trs (s/spec (s/* ::maths/Triangle)))

Или используйте другую спецификацию без регулярных выражений для описания аргумента последовательности:

(s/cat :trs (s/coll-of ::maths/Triangle))

Ваш пример спецификации будет работать , если ваша функция будет переменной, потому что s/cat и s/* сочетаются с описанием одной последовательности с нулем или более элементов.

(defn adder [& nums] (apply + nums))
(s/fdef adder :args (s/cat :nums (s/* int?)))
(st/instrument `adder)
(adder 1 2 3)
...