【问题标题】:A Clojure Spec for a predicate function谓词函数的 Clojure 规范
【发布时间】:2017-04-18 14:28:17
【问题描述】:

我想为函数作为谓词的含义编写一个规范。在 Clojure 世界中,似乎有三种方法可以了解谓词是什么,尽管大多数人似乎都同意它们应该以问号结尾。

  1. 接受一个参数并返回真或假的函数。
  2. 接受一个参数并返回 true、false 或 nil 的函数。
  3. 接受一个参数并返回真值或假值的函数。

Jira Ticket on what Predicate is.

编辑:谓词也可以采用多个参数,例如 contains?。

【问题讨论】:

  • 保持简单;坚持(1)!

标签: clojure clojure.spec


【解决方案1】:

我认为谓词最准确的规范是:

(s/fspec :args (s/cat :v any?) :ret any?)

虽然谓词通常返回真/假,但并不要求它们这样做 - 唯一需要的协定是它接受一个值并返回一个将被视为逻辑真值的值。

【讨论】:

    【解决方案2】:

    如果我理解 clojure.spec/fdef 正确,它允许我们制定问题中描述的规范。

    (spec/fdef ::predicate-1
               :args (spec/cat :arg any?)
               :ret  boolean?)
    

    我们可以通过传递一些我们知道应该通过或失败测试的示例来测试:

    (spec/valid? ::predicate-1 boolean?)       => true
    (spec/valid? ::predicate-1 (fn [a] 5))     => false
    (spec/valid? ::predicate-1 (fn [a] true))  => true
    (spec/valid? ::predicate-1 (fn [a b] true))=> false
    (spec/valid? ::predicate-1 #(= 10 %))      => true
    (spec/valid? ::predicate-1 (fn [a] nil))   => false
    

    用于防御 nr。 2:

    (spec/fdef ::predicate-2
               :args (spec/cat :arg any?)
               :ret  (spec/nilable boolean?))
    
    (spec/valid? ::predicate-2 (fn [a] nil))   => true
    

    对于天然橡胶。 3 任何接受一个参数的函数都是有效的,因为 clojure 中的所有内容要么是真要么是假。

    (spec/fdef ::predicate-3
               :args (spec/cat :arg any?)
               :ret  any?)
    
    (spec/valid? ::predicate-3 identity)       => true
    (spec/valid? ::predicate-3 str)            => true
    

    我们似乎能够做的一件有趣的事情是让规范为我们生成这样的函数:

    (let [p (gen/generate (spec/gen ::pedicate-1))]
      (clojure.string/join
       " " [(p 0) (p 1) (p -1) (p nil) (p 'a) (p :a) (p (fn [a] a))]))
    => "false true true false true false false"
    

    除此之外,我们也许可以尝试猜测生成的函数的作用。但是如果无法查看来源,我们将很难检查我们的猜测是否正确。

    【讨论】:

    • 我的印象是正确的,您发布了您立即回答的问题(而不是第一次)?您的答案与您的问题在同一秒发布...
    • @PiotrekBzdyl 是的。当您提出关于 SO 的问题时,您可以选择自己以问答方式回答问题,就像它所写的那样。
    • 是的,我知道您可以在找到解决方案后回答您自己的问题。这是我第一次看到有人使用 SO 作为一种博客来同时记录问题和答案(所以这不是发布问题,因此有人可以帮助回答 - 包括提问的人)和这就是为什么我很困惑。
    • clojure 社区最近通过 slack 回答了大多数人的问题。一些特别优秀的clojurists以这种方式将他们在那里提出的任何问题转移到stackoverflow,以便下一个遇到问题的人可以更轻松地找到答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 2017-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 2016-01-09
    相关资源
    最近更新 更多