簡體   English   中英

Clojure 規范:如何將元組指定為 function 參數?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM