[英]How do I write a Clojure Spec for a function that takes a sequence argument?
[英]Clojure Spec: How can I spec a tuple as a function argument?
我在 Clojure 中有一個 function ,它接受一個 2 元素向量作為參數:
(defn influence [[school value]])
我想使用我已注冊的現有規范為 function 編寫 arguments 的規范:
(s/fdef influence :args (s/cat :arg (s/cat :school ::school, :value ::value))
但是,這不起作用,嵌套s/cat
調用在頂層運行並將::school
的規范應用於整個參數列表。 還有一個名為s/tuple
的 function ,這可能表明您可以這樣做
(s/fdef ->influence :args (s/cat :influence (s/tuple ::school ::value)))
但這也行不通。 Spec 似乎以某種方式感到困惑並嘗試使規范名稱符合規范:
val: :my.ns/school fails spec: :my.ns/school at: [:args:school] predicate...
您可以使用 2 個參數的常規 function 開始:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as stest]
))
(defn name-age
[name age]
(format "name=%s age=%d" name age))
(s/fdef name-age
:args (s/cat
:name string?
:age pos-int? ) )
(dotest
(spyx (name-age "joe" 42))
(stest/instrument `name-age)
(throws? (spyx (name-age "jill" :24))))
結果
(name-age ["joe" 42]) => "name=joe age=42"
然后將其重寫為 1 個 arg 的 fn,它是一個元組:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as stest] ))
(s/def ::name string?)
(s/def ::age pos-int?)
(s/def ::na-tup (s/cat :name-arg ::name :age-arg ::age))
(defn name-age
[na-tup]
(s/valid? ::na-tup na-tup)
(let [[name age] na-tup]
(s/valid? ::name name)
(s/valid? ::age age)
(format "name=%s age=%d" name age)))
(s/fdef name-age
:args (s/cat
:name ::name
:age ::age ) )
(dotest
(spyx (name-age ["joe" 42]))
(stest/instrument `name-age)
(throws? (spyx (name-age ["jill" :24]))) )
如果需要,您還可以獲得一些幫助,以解構name-age
function 中的數據:
(s/conform ::na-tup na-tup) =>
{:name-arg "joe", :age-arg 42}
我研究了 Clojure 規范文檔並將它們制作成可以在此處看到的實時單元。 可能會在某個時候將它們分解為單獨的回購。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.