Clojure Spec,用于包含falsey值的集合

时间:2017-05-24 15:24:47

标签: clojure clojure.spec

出于某种原因,以下规范确实说false不是有效的::a-thing,即使它是给定集的一部分。

(require '[clojure.spec.alpha :as spec])

(spec/def ::a-thing #{:a :b :c false})

(spec/valid? ::a-thing :a)     ; => true
(spec/valid? ::a-thing :d)     ; => false
(spec/valid? ::a-thing false)  ; => false

2 个答案:

答案 0 :(得分:4)

这与spec无关,而与集合如何表现为函数有关。每当您使用集合作为测试成员资格的函数时,您将会遇到类似的误解。

当您通过spec 函数时,它会将其用作谓词。集合是函数,就像实现clojure.lang.IFn的任何其他函数一样。作为函数,集合在其成员上表现为身份。一切都随之而来。 spec 不会特意处理集合。

答案 1 :(得分:1)

事实证明,Spec中给出的集合中不允许有虚假的东西 因为它使用集合本身作为检查成员资格的函数而不是 contains?函数。正如我们在下面看到的,一组将返回 给定参数,如果它是集合的成员,否则为nil。

(#{:a :b :c false} :a)    ; => :a
(#{:a :b :c false} false) ; => false
(#{:a :b :c false} :d)    ; => nil

这当然是造成误解的原因。

我们必须自己手动将该集合包装在contains中,以使规范正常运行。

(spec/def ::a-thing #(contains? #{:a :b :c false} %))