2024 Clojure 状态调查中分享您的想法!

欢迎!请查看关于页面获取更多有关如何使用本站的信息。

0
Spec

这个函数的最简单规范方法是什么?具体来说是:fn部分。

(s/def ::edges #{0.149 0.150 0.050})
(s/def ::result #{:correct :incorrect})

(s/fdef foo
        :args (s/cat :student-response ::edges :authoritative-answer ::edges)
        :ret ::result
:fn ? )

基本上,如果将student-response四舍五入到小数点后一位与四舍五入到小数点后一位的authoritative-answer相匹配,那么函数返回:correct,否则返回:incorrect

我选择了会触及四舍五入边界的值,而不是寄希望于数字生成过程会偶然触碰到这些边界。

2 个答案

0
 
最佳答案

好的。以下是我在使用的方法,并且它工作。还有更简单的方法吗?

(defn- round [some-number to]
  (double (/ (Math/round (double (* (/ 1 to) some-number))) (/ 1 to))))

(s/def ::edges #{0.149 0.150 0.050})
(s/def ::result #{:correct :incorrect})

(s/fdef foo
        :args (s/cat :student-value ::edges :authoritative-value ::edges)
        :ret ::result
        :fn (s/or
              :correct-answer (s/and #(= (round (-> % :args :student-value) 0.1)
                                         (round (-> % :args :authoritative-value) 0.1))
                                     #(= (:ret %) :correct))
              :incorrect-answer (s/and #(not= (round (-> % :args :student-value) 0.1)
                                              (round (-> % :args :authoritative-value) 0.1))
                                       #(= (:ret %) :incorrect))
              )
        )
+1

我怀疑您可能只是复制了foo中的逻辑来做出这个决定,因此我认为添加一个:fn不太有价值。通常只有当它可以在args和ret之间验证一些与函数本身逻辑独立的约束时,添加:fn才有用。

对我来说,测试确实代表了一种类似于复式簿记的冗余。因此,我编写这个规范以便在clojure.test中执行,作为编写常规测试的替代方案。

我提供的例子旨在帮助我了解如何在规范中最好地表达此类关系,因为我对此还是新手。
...