Clojure spec:实际上使用“ spec”代替“ coll-of”中的“ pred”。可以吗?

时间:2019-08-04 14:17:57

标签: clojure clojure.spec

我正在尝试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的文档说:

  

用法:(按条件排序和选择)

     

返回满足pred的项目集合的规范。不像   coll-of会完全符合每个值。

但是,作为第一个参数,我没有使用pred(一个接受参数检查并返回真实值的函数),而是另一个规范(一个有参数接受检查并返回的函数)我不确定什么),在这种情况下,该规范是在::mustbe-vec-of-2-int下注册的。

这非常好用。

这种正确的样式是否可以正常工作?

PS

(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))

1 个答案:

答案 0 :(得分:3)

  

这是正确的样式并且可以使用吗?

是的。规范,可以解析为规范的关键字以及简单谓词功能可以在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注册表,将关键字与spec值相关联。当您将::some-spec-keyword传递给clojure.spec API时,它将自行从注册表中解析规范值。您还可以“别名”规范,例如(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])