Как написать спецификацию Clojure для функции, которая принимает аргумент последовательности?

Я пишу функцию, которая принимает последовательность треугольников (которые на самом деле представлены как 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?

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

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

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

Примечание. ::Triangle определяется:

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

person interstar    schedule 11.09.2018    source источник


Ответы (1)


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

Вы можете избежать этого поведения, заключив внутреннюю спецификацию регулярного выражения 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)
person Taylor Wood    schedule 11.09.2018
comment
А... вот так. Спасибо. Это сводило меня с ума, потому что я не видел ничего плохого в том, что делал. - person interstar; 11.09.2018
comment
Спасибо, мне тоже было полезно :) - person fl00r; 11.09.2018