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中执行,以验证函数的实现,作为编写常规测试的替代方案。

我提供的例子旨在帮助我理解如何在规范中最好地表达这些类型的关系,因为我对于这一块还不是很熟悉。
...