【问题标题】:How do I write a Clojure Spec for a function that takes a sequence argument?如何为接受序列参数的函数编写 Clojure 规范?
【发布时间】:2018-09-11 14:55:52
【问题描述】:

我正在编写一个函数,它采用一系列三角形(实际上表示为maps)。

我的规格是:

(s/fdef triangle-list-to-pattern
        :args (s/cat :trs (s/* ::maths/Triangle))
        )

该函数接受一个参数,trs,它是一个三角形序列。

但是,当我检测并调用此函数时,出现以下故障:

fails spec: :patterning.maths/Triangle at: [:args :trs] predicate: map?

如果我使用规范明确测试我传递给函数的参数,它就会通过。它实际上只是一系列符合三角形标准的事物。

该功能似乎正在运行。该论点似乎是正确的,并且在单独测试时通过了规范。所以我想我弄错了fdef

有什么问题?

注意,::Triangle 已定义:

(s/def ::Triangle (s/keys :req-un [::A ::B ::C ::a ::b ::c ::ax ::ay ::bx ::by ::cx ::cy]))

【问题讨论】:

    标签: clojure clojure.spec


    【解决方案1】:

    您的:args 规范不起作用的原因是regex specs 组合来描述嵌套时的单个序列。

    您可以通过将内部正则表达式规范 s/* 包装在 s/spec 中来避免这种行为:

    (s/cat :trs (s/spec (s/* ::maths/Triangle)))
    

    或者使用不同的非正则表达式规范来描述序列参数:

    (s/cat :trs (s/coll-of ::maths/Triangle))
    

    如果您的函数是可变参数,您的示例规范工作,因为 s/cats/* 正在组合描述具有零个或多个元素的单个序列。

    (defn adder [& nums] (apply + nums))
    (s/fdef adder :args (s/cat :nums (s/* int?)))
    (st/instrument `adder)
    (adder 1 2 3)
    

    【讨论】:

    • 啊……就是这样。谢谢。这让我很生气,因为我看不出我所做的有什么问题。
    • 谢谢,这对我也很有用:)
    猜你喜欢
    • 2023-01-30
    • 2012-02-20
    • 1970-01-01
    • 2019-03-04
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    相关资源
    最近更新 更多