包含错误值的集合的Clojure规范

包含错误值的集合的Clojure规范,clojure,clojure.spec,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
不是有效的
::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

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

(#{:a :b :c false} :a)    ; => :a
(#{:a :b :c false} false) ; => false
(#{:a :b :c false} :d)    ; => nil
这当然是造成误解的原因

为了使规范正常工作,我们必须手动将集合包装在
包含的

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

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

(#{:a :b :c false} :a)    ; => :a
(#{:a :b :c false} false) ; => false
(#{:a :b :c false} :d)    ; => nil
这当然是造成误解的原因

为了使规范正常工作,我们必须手动将集合包装在
包含的

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

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


当您传递
spec
函数时,它将它用作谓词。集合是函数,其他任何实现都是函数。作为函数,集合在其成员上表现为标识。其他一切都随之而来集合绝不会受到
spec

的特殊处理,这与
spec
无关,一切都与集合作为函数的行为有关。当您使用集合作为函数来测试成员资格时,您会遇到类似的误解


当您传递
spec
函数时,它将其用作谓词。集合是函数,其他任何实现都是函数。作为函数,集合在其成员上表现为标识。其他一切都随之而来集合绝对不是由
spec

专门处理的,不是这样。虚假的事情是允许的——它们不会产生你期望的结果。无论是由
spec
还是其他地方使用包含假值的集合作为谓词,都是如此。这是一个没有区别的区别。集合不应用作谓词。规范指南错误地指示用户使用集合作为谓词,而不是用户使用它们。@Rovanion这绝不是一般不鼓励使用集合作为规范谓词的理由。你的问题是关于一个仅适用于包含
nil
false
的集合的角案例,这在实践中很少见到。我同意这是错误的。但是
spec
本身不是。“除了
nil
false
”这个短语放在正确的位置可以解决这个问题,但事实并非如此。虚假的事情是允许的——它们不会产生你期望的结果。无论是由
spec
还是其他地方使用包含假值的集合作为谓词,都是如此。这是一个没有区别的区别。集合不应用作谓词。规范指南错误地指示用户使用集合作为谓词,而不是用户使用它们。@Rovanion这绝不是一般不鼓励使用集合作为规范谓词的理由。你的问题是关于一个仅适用于包含
nil
false
的集合的角案例,这在实践中很少见到。我同意这是错误的。但是
spec
本身不是。短语“除了
nil
false
”在正确的位置将修复它。