谓词函数的Clojure规范

谓词函数的Clojure规范,clojure,clojure.spec,Clojure,Clojure.spec,我想为函数作为谓词的含义编写一个规范。在Clojure世界中,关于谓词是什么,似乎有三种方法,尽管大多数人似乎都同意它们应该以问号结尾 接受一个参数并返回true或false的函数 接受一个参数并返回true、false或nil的函数 一种函数,它接受一个参数并返回一个真值或假值 编辑:谓词也可以接受多个参数,如包含?所示,如果我理解clojure.spec/fdef正确,它允许我们制定与问题中所述类似的规范 (spec/fdef ::predicate-1 :args

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

  • 接受一个参数并返回true或false的函数
  • 接受一个参数并返回true、false或nil的函数
  • 一种函数,它接受一个参数并返回一个真值或假值

  • 编辑:谓词也可以接受多个参数,如
    包含?

    所示,如果我理解
    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
    
    第2项抗辩:

    (spec/fdef ::predicate-2
               :args (spec/cat :arg any?)
               :ret  (spec/nilable boolean?))
    
    (spec/valid? ::predicate-2 (fn [a] nil))   => true
    
    对于nr.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
    
    然后,我们似乎可以做一件有趣的事情,让spec为我们生成这样的函数:

    (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"
    

    由此我们可以猜测生成的函数是做什么的。但是如果看不到源代码,我们将很难检查我们的猜测是否正确。

    如果我理解了
    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
    
    第2项抗辩:

    (spec/fdef ::predicate-2
               :args (spec/cat :arg any?)
               :ret  (spec/nilable boolean?))
    
    (spec/valid? ::predicate-2 (fn [a] nil))   => true
    
    对于nr.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
    
    然后,我们似乎可以做一件有趣的事情,让spec为我们生成这样的函数:

    (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"
    

    由此我们可以猜测生成的函数是做什么的。但是如果看不到来源,我们将很难检查我们的猜测是否正确。

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

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

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

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

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

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

    我的印象正确吗,您发布了立即回答的问题(不是第一次)?你的答案与你的问题在同一秒发布…@PiotrekBzdyl-Yes。当你提出问题时,你可以选择自己回答问题,就像上面写的那样。是的,我知道一旦你找到了解决方案,你可以回答自己的问题。这是我第一次看到有人使用SO作为一种博客,同时记录问题和答案(因此这不是一个发布问题以便有人可以帮助回答,包括提问的人),这就是为什么我感到困惑。clojure社区回答了最近通过slack提出的大多数问题。一些特别优秀的法学家将他们在那里提出的任何问题以这种方式转移到stackoverflow,以便下一个有问题的人能够更容易地找到答案。我的印象是否正确,即你发布了你立即回答的问题(而不是第一次)?你的答案与你的问题在同一秒发布…@PiotrekBzdyl-Yes。当你提出问题时,你可以选择自己回答问题,就像上面写的那样。是的,我知道一旦你找到了解决方案,你可以回答自己的问题。这是我第一次看到有人使用SO作为一种博客,同时记录问题和答案(因此这不是一个发布问题以便有人可以帮助回答,包括提问的人),这就是为什么我感到困惑。clojure社区回答了最近通过slack提出的大多数问题。一些特别优秀的法学家用这种方式将他们在那里提出的任何问题转移到stackoverflow,以便下一个有问题的人能够更容易地找到答案;坚持(1)!保持简单;坚持(1)!