请在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并不会特别有价值。通常只有当可以验证arg和ret之间的一些独立于函数自身逻辑的约束时,添加:fn才会有用。

by
对我来说,测试确实代表了一种冗余,就像双倍登记会计一样。因此,我编写这个规范,在clojure.test中执行,以验证函数的实现,作为编写常规测试的替代方案。

我所提供的示例旨在帮助我理解如何在规范中最好地表达这些类型的关系,因为我刚开始接触这些。
...