如何只接受规范中的有序集合
How to accept only ordered collections in spec
我如何制定一个只接受顺序(即保留顺序)集合的规范?
例如
cljs.user=> (s/def ::path (s/+ number?))
:cljs.user/path
cljs.user=> (s/explain ::path [])
val: () fails spec: :cljs.user/path predicate: number?, Insufficient input
:cljs.spec.alpha/spec :cljs.user/path
:cljs.spec.alpha/value []
cljs.user=> (s/explain ::path [1 2 3])
Success!
符合预期,但同时注意顺序
cljs.user=> #{1 2 3}
#{1 3 2}
cljs.user=> (s/explain ::path #{1 2 3})
Success!
这似乎没有任何意义。那么一个次要问题:
为什么规范中的序列相关表达式(cat、*、+、?)接受序列中断集合?
UPD 我弄乱了 sequential/ordered 原始问题中的区别。清理术语。
How can I make a spec that accepts only order-preserving collections?
有一个 clojure.core 谓词函数 sorted?
对于实现 Sorted
.
的集合 return 为真
(sorted? (sorted-map))
=> true
对于内容恰好已排序但未实现的集合,return 并非如此 Sorted
:
(sorted? [1 2 3])
=> false
您可以在规范中使用任意谓词函数,因此您可以定义一个 return 对具有排序内容的集合为真的函数:
(defn ordered? [coll]
(or (empty? coll) (apply <= coll)))
(ordered? [1 2 3])
=> true
然后您可以使用 s/and
将此谓词与您的正则表达式规范结合起来:
(s/def ::path (s/and (s/+ number?)
ordered?))
(s/explain ::path [1 2 3])
Success!
=> nil
(s/explain ::path #{1 2 3})
val: [1 3 2] fails spec: :playground.so/path predicate: ordered?
=> nil
序列规范(正则表达式规范)不应匹配有序,即 顺序 集合。这是一个错误,已在当前版本的规范中修复,请参阅 CLJ-2183。
在 Clojure 1.10.0-RC5 中,结果符合预期:
(s/conform ::path [1 2 3]) ; => [1 2 3]
(s/conform ::path #{1 2 3}) ; => :clojure.spec.alpha/invalid
(s/explain ::path #{1 2 3})
;; #{1 3 2} - failed: (or (nil? %) (sequential? %)) spec: :user/path
您可以在最后一行中看到正则表达式规范现在仅匹配 sequential?
.
的值
我如何制定一个只接受顺序(即保留顺序)集合的规范?
例如
cljs.user=> (s/def ::path (s/+ number?))
:cljs.user/path
cljs.user=> (s/explain ::path [])
val: () fails spec: :cljs.user/path predicate: number?, Insufficient input
:cljs.spec.alpha/spec :cljs.user/path
:cljs.spec.alpha/value []
cljs.user=> (s/explain ::path [1 2 3])
Success!
符合预期,但同时注意顺序
cljs.user=> #{1 2 3}
#{1 3 2}
cljs.user=> (s/explain ::path #{1 2 3})
Success!
这似乎没有任何意义。那么一个次要问题:
为什么规范中的序列相关表达式(cat、*、+、?)接受序列中断集合?
UPD 我弄乱了 sequential/ordered 原始问题中的区别。清理术语。
How can I make a spec that accepts only order-preserving collections?
有一个 clojure.core 谓词函数 sorted?
对于实现 Sorted
.
(sorted? (sorted-map))
=> true
对于内容恰好已排序但未实现的集合,return 并非如此 Sorted
:
(sorted? [1 2 3])
=> false
您可以在规范中使用任意谓词函数,因此您可以定义一个 return 对具有排序内容的集合为真的函数:
(defn ordered? [coll]
(or (empty? coll) (apply <= coll)))
(ordered? [1 2 3])
=> true
然后您可以使用 s/and
将此谓词与您的正则表达式规范结合起来:
(s/def ::path (s/and (s/+ number?)
ordered?))
(s/explain ::path [1 2 3])
Success!
=> nil
(s/explain ::path #{1 2 3})
val: [1 3 2] fails spec: :playground.so/path predicate: ordered?
=> nil
序列规范(正则表达式规范)不应匹配有序,即 顺序 集合。这是一个错误,已在当前版本的规范中修复,请参阅 CLJ-2183。
在 Clojure 1.10.0-RC5 中,结果符合预期:
(s/conform ::path [1 2 3]) ; => [1 2 3]
(s/conform ::path #{1 2 3}) ; => :clojure.spec.alpha/invalid
(s/explain ::path #{1 2 3})
;; #{1 3 2} - failed: (or (nil? %) (sequential? %)) spec: :user/path
您可以在最后一行中看到正则表达式规范现在仅匹配 sequential?
.