Clojure规范:如何将元组规范为函数参数?
我在Clojure中有一个函数,它接受2元素向量作为参数:Clojure规范:如何将元组规范为函数参数?,clojure,clojure.spec,Clojure,Clojure.spec,我在Clojure中有一个函数,它接受2元素向量作为参数: (defn影响[[学校价值]) 我想使用已注册的现有规范为该函数的参数编写规范: (s/fdef影响:args(s/cat:arg(s/cat:school::school,:value::value)) 但是,这不起作用,嵌套的s/cat调用在顶层运行,并将:school的规范应用于整个参数列表。还有一个名为s/tuple的函数,它可能建议您可以这样做 (s/fdef->impact:args(s/cat:impact(s/tup
(defn影响[[学校价值])
我想使用已注册的现有规范为该函数的参数编写规范:
(s/fdef影响:args(s/cat:arg(s/cat:school::school,:value::value))
但是,这不起作用,嵌套的s/cat
调用在顶层运行,并将:school
的规范应用于整个参数列表。还有一个名为s/tuple
的函数,它可能建议您可以这样做
(s/fdef->impact:args(s/cat:impact(s/tuple::school::value)))
但这也不起作用。Spec似乎不知怎么搞混了,并试图使Spec名称与Spec一致:
val::my.ns/school失败spec::my.ns/school at:[:args:school]谓词…
您可以使用两个args的常规函数这样开始:
(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
函数中获得一些帮助来分解数据:
(s/conform ::na-tup na-tup) =>
{:name-arg "joe", :age-arg 42}
实时代码示例
我研究了Clojure Spec文档,并将它们制作成活动单元。可能会在某个时候将它们分解成单独的回购。您可以使用两个参数的常规函数开始这样做:
(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
函数中获得一些帮助来分解数据:
(s/conform ::na-tup na-tup) =>
{:name-arg "joe", :age-arg 42}
实时代码示例 我研究了Clojure规范文档,并将它们制作成活的单元,可能会在某个时候将它们分解成单独的回购协议