Используйте Clojure Spec для проверки согласованности типов на минусы? - PullRequest
0 голосов
/ 27 мая 2018

Если я запускаю библиотеку с заемщиками и книгами:

(s/def ::brs (s/coll-of ::br/borrower))
(s/def ::bks (s/coll-of ::bk/book))

И мне нужна универсальная функция, которая добавляет элемент в любую коллекцию:

(defn add-item [x xs]
  (if (some #{x} xs)
    xs
    (cons x xs)))

Как мне написатьспецификация, которая гарантирует, что я не могу добавить книгу заемщикам и наоборот?

Потому что эта спецификация:

(s/fdef add-item
    :args (s/fspec :args (s/or :is-brs (s/and (s/cat :x ::br/borrower) (s/cat :xs ::brs))
                               :is-bks (s/and (s/cat :x ::bk/book) (s/cat :xs ::bks))))
    :ret (s/or :ret-brs ::brs
               :ret-bks ::bks))

не работает.: - (

Спасибо за помощь!

1 Ответ

0 голосов
/ 27 мая 2018

Использование определений int / string для ::brs и ::bks:

(s/def ::brs (s/coll-of int?))
(s/def ::bks (s/coll-of string?))

Это должно работать:

(s/fdef add-item
        :args (s/or
                :brs (s/cat :x int? :xs ::brs)
                :bks (s/cat :x string? :xs ::bks))
        :ret (s/or :brs ::brs
                   :bks ::bks))
;; instrument function here
(add-item 1 [2])
=> (1 2)
(add-item "1" [2]) ;; throws exception
...