vararg函数上的Clojure规范

vararg函数上的Clojure规范,clojure,specifications,clojure.spec,Clojure,Specifications,Clojure.spec,我正在尝试为一个合并函数编写一个规范,它将函数和映射作为输入,并使用函数来解决冲突。但是,我为函数编写的规范失败了。我正试图找出如何为这些函数编写规范 下面是代码片段 (require '[clojure.spec.test :as stest]) (require '[clojure.spec :as spec]) (defn deep-merge-with [func & maps] (let [par-func (partial deep-merge-with func)]

我正在尝试为一个合并函数编写一个规范,它将函数和映射作为输入,并使用函数来解决冲突。但是,我为函数编写的规范失败了。我正试图找出如何为这些函数编写规范

下面是代码片段

(require '[clojure.spec.test :as stest])
(require '[clojure.spec :as spec])

(defn deep-merge-with [func & maps] 
  (let [par-func (partial deep-merge-with func)] 
    (if (every? map? maps) 
        (apply merge-with par-func maps) 
        (apply func maps))))

(spec/fdef deep-merge-with
           :args (spec/cat :func (spec/fspec :args (spec/cat :maps (spec/* map?))
                                             :ret map?)
                           :maps (spec/cat :maps (spec/* map?)))
           :ret map?)

(stest/instrument `deep-merge-with)

(deep-merge-with (fn [f s] s) {:a 1} {:a 2})
我得到的规格错误是:

clojure.lang.ExceptionInfo: Call to #'boot.user/deep-merge-with did not conform to spec:
    In: [0] val: () fails at: [:args :func] predicate: (apply fn),  Wrong number of args (0) passed to: user/eval22001/fn--22002
                                :clojure.spec/args  (#function[boot.user/eval22001/fn--22002] {:a 1} {:a 2})

在您的
[:args:func]
规范中:

(spec/fspec :args (spec/cat :maps (spec/* map?)) :ret map?)
您的意思是函数必须接受任意数量的映射作为参数并返回一个映射。但是传递给
深度合并的函数不符合该规范:

(fn [f s] s)

此函数只接受两个参数,而不是任意数量的映射。

[:args:func]
规范中:

(spec/fspec :args (spec/cat :maps (spec/* map?)) :ret map?)
您的意思是函数必须接受任意数量的映射作为参数并返回一个映射。但是传递给
深度合并的函数不符合该规范:

(fn [f s] s)

此函数只接受两个参数,而不是任意数量的映射。

(与(fn[&maps](last maps))深度合并({:a 1}{:a 2})
也不起作用,我们如何在
(fn[f s]s)
上强制spec以使spec只接受两个参数。@Vijay您可以使用
(spec/cat:m1 map?:m2 map?)
对于一个
:args
函数的规范,它只接受两个映射参数。非常感谢,它帮助我调试了这个问题,我很笨,我的函数输入不是映射,在深度合并过程中,当调用与func的合并时,它实际上会传递函数的冲突值。所以像这样的规范可以工作
(spec/fdef与:args深度合并)(spec/cat:func(spec/fspec:args(spec/cat:m1::spec/any:m2::spec/any):ret::spec/any):maps(spec/cat:maps(spec/*::spec/any)):ret map?
我不知道如何标记你的答案是否正确,请help@Vijay你应该可以点击我帖子旁边的上/下投票按钮下面的灰色箭头来接受我的答案。
(与(fn[&maps](last maps))深度合并({:a 1}{:a 2})
也不起作用,我们如何在
(fn[f s]s)上强制spec
使spec正好包含两个参数。@Vijay你可以使用
(规格/类别:m1图?:m2图?)
对于一个
:args
函数的规范,该函数只接受两个映射参数。非常感谢,它帮助我调试了这个问题,我很笨,我的函数输入不是映射,在深度合并过程中,当调用与func的合并时,它实际上会传递函数的冲突值。因此类似的规范将起作用
(spec/fdef与:args深度合并(spec/cat:func(spec/fspec:args(spec/cat:m1::spec/any:m2::spec/any):ret::spec/any):映射(spec/cat:maps(spec/*::spec/any)):ret映射?)
我不知道如何将您的答案标记为正确help@Vijay你应该可以点击我帖子旁边的上/下投票按钮下方的灰色箭头来接受我的答案。