Clojure 规范:在 "coll-of" 中使用 "spec" 而不是 "pred" 确实有效。这个可以吗?
Clojure spec: Using a "spec" instead of a "pred" in "coll-of" actually works. Is this ok?
我正在尝试 Clojure spec 并从函数 :pre
约束中调用它。
我的规范 ::mustbe-seql-of-vec-of-2-int
将检查传递给函数的参数是否是从 0 到 4 个恰好 2 个整数的向量的序列:
(require '[clojure.spec.alpha :as s])
(s/def ::mustbe-seql-of-vec-of-2-int
(s/and
::justprint
(s/coll-of
::mustbe-vec-of-2-int
:kind sequential?
:min-count 0
:max-count 4)))
因此规范由其他规范组成,特别是 ::justprint
除了打印传递的参数以进行调试和 coll-of 之外什么都不做,以测试集合参数。
coll-of 的文档说:
Usage: (coll-of pred & opts)
Returns a spec for a collection of items satisfying pred. Unlike
'every', coll-of will exhaustively conform every value.
但是,作为第一个参数,我没有使用 pred(一个接受要检查的参数并返回真值的函数),而是另一个规范(一个接受要检查的参数并返回的函数)不确定是什么),在这种情况下,规范在 ::mustbe-vec-of-2-int
.
下注册
这非常有效。
这种风格是否正确并且有望奏效?
P.S.
(s/def ::justprint
#(do
; "vec" to realize the LazySeq, which is not realized by join
(print (d/join [ "::justprint ▶ " (vec %) "\n"] ))
true))
(s/def ::mustbe-vec-of-2-int
(s/coll-of integer? :kind vector? :count 2))
Is this correct style and expected to work?
是的。规范、可以解析为规范的关键字和普通谓词函数可以在 clojure.spec API 的许多部分互换使用。 "Pred" 在该文档字符串的上下文中比一般的 Clojure 谓词函数具有更广泛的含义,例如nil?
.
(require '[clojure.spec.alpha :as s])
(s/conform int? 1) ;; => 1
(s/conform int? false) ;; => :clojure.spec.alpha/invalid
s/def
修改 clojure.spec 注册表,将关键字与规范值相关联。当您将 ::some-spec-keyword
传递给 clojure.spec API 时,它会从注册表中自行解析规范值。您还可以 "alias" 规格,例如(s/def ::foo ::bar)
.
(s/def ::even-int? (s/and int? even?))
(s/conform ::even-int? 2) ;; => 2
(s/conform ::even-int? 3) ;; => :clojure.spec.alpha/invalid
所以这些都是等价的:
(s/conform (s/coll-of (s/and int? even?)) [2 4 6 8])
(s/conform (s/coll-of ::even-int?) [2 4 6 8])
(s/def ::coll-of-even-ints? (s/coll-of ::even-int?))
(s/conform ::coll-of-even-ints? [2 4 6 8])
我正在尝试 Clojure spec 并从函数 :pre
约束中调用它。
我的规范 ::mustbe-seql-of-vec-of-2-int
将检查传递给函数的参数是否是从 0 到 4 个恰好 2 个整数的向量的序列:
(require '[clojure.spec.alpha :as s])
(s/def ::mustbe-seql-of-vec-of-2-int
(s/and
::justprint
(s/coll-of
::mustbe-vec-of-2-int
:kind sequential?
:min-count 0
:max-count 4)))
因此规范由其他规范组成,特别是 ::justprint
除了打印传递的参数以进行调试和 coll-of 之外什么都不做,以测试集合参数。
coll-of 的文档说:
Usage: (coll-of pred & opts)
Returns a spec for a collection of items satisfying pred. Unlike 'every', coll-of will exhaustively conform every value.
但是,作为第一个参数,我没有使用 pred(一个接受要检查的参数并返回真值的函数),而是另一个规范(一个接受要检查的参数并返回的函数)不确定是什么),在这种情况下,规范在 ::mustbe-vec-of-2-int
.
这非常有效。
这种风格是否正确并且有望奏效?
P.S.
(s/def ::justprint
#(do
; "vec" to realize the LazySeq, which is not realized by join
(print (d/join [ "::justprint ▶ " (vec %) "\n"] ))
true))
(s/def ::mustbe-vec-of-2-int
(s/coll-of integer? :kind vector? :count 2))
Is this correct style and expected to work?
是的。规范、可以解析为规范的关键字和普通谓词函数可以在 clojure.spec API 的许多部分互换使用。 "Pred" 在该文档字符串的上下文中比一般的 Clojure 谓词函数具有更广泛的含义,例如nil?
.
(require '[clojure.spec.alpha :as s])
(s/conform int? 1) ;; => 1
(s/conform int? false) ;; => :clojure.spec.alpha/invalid
s/def
修改 clojure.spec 注册表,将关键字与规范值相关联。当您将 ::some-spec-keyword
传递给 clojure.spec API 时,它会从注册表中自行解析规范值。您还可以 "alias" 规格,例如(s/def ::foo ::bar)
.
(s/def ::even-int? (s/and int? even?))
(s/conform ::even-int? 2) ;; => 2
(s/conform ::even-int? 3) ;; => :clojure.spec.alpha/invalid
所以这些都是等价的:
(s/conform (s/coll-of (s/and int? even?)) [2 4 6 8])
(s/conform (s/coll-of ::even-int?) [2 4 6 8])
(s/def ::coll-of-even-ints? (s/coll-of ::even-int?))
(s/conform ::coll-of-even-ints? [2 4 6 8])