比方說,我有一個函數,它接受一個函數並返回一個函數,該函數應用它傳遞給函數的任何參數,並將結果放入一個向量中(這是一個不好的例子,但希望能夠說明我的觀點)。如何在Clojure中指定高階函數參數?
(defn box [f]
(fn [& args]
[(apply f args)]))
我認爲存儲箱功能的規格看起來像這樣
(spec/fdef box
:args (spec/cat :function (spec/fspec :args (spec/* any?)
:ret any?))
:ret (spec/fspec :args (spec/* any?)
:ret (spec/coll-of any? :kind vector? :count 1)))
如果我當時儀器箱功能
(spec-test/instrument)
和呼叫與clojure.core盒/ +我得到例外
(box +)
ExceptionInfo Call to #'user/box did not conform to spec:
In: [0] val: ([]) fails at: [:args :function] predicate: (apply fn), Cannot cast clojure.lang.PersistentVector to java.lang.Number
:clojure.spec.alpha/args (#function[clojure.core/+])
:clojure.spec.alpha/failure :instrument
:clojure.spec.test.alpha/caller {:file "form-init4108179545917399145.clj", :line 1, :var-scope user/eval28136}
clojure.core/ex-info (core.clj:4725)
如果我正確地理解錯誤,那麼它將採取任何措施?謂詞併爲測試生成一個PersistentVector,該clojure.core/+顯然不能使用。這意味着我可以得到它通過改變框的參數功能規格工作是
(spec/fspec :args (spec/* number?)
:ret number?)
,但如果我想用框都clojure.core/+和clojure.string /小寫呢?
N.B.要獲得規範在REPL工作,我需要
:dependencies [[org.clojure/clojure "1.9.0-alpha16"]]
:profiles {:dev {:dependencies [[org.clojure/test.check "0.9.0"]]}}
:monkeypatch-clojure-test false
在project.clj及以下進口
(require '[clojure.spec.test.alpha :as spec-test])
(require '[clojure.spec.alpha :as spec])