2017-04-18 84 views
1

我想写一个关于函数作为谓词的含义的规范。似乎有三种方式可以解释Clojure世界中的谓词,尽管大多数人似乎都认为它们应该以问号结尾。谓词函数的Clojure规范

  1. 函数接受一个参数并返回true或false。
  2. 一个函数,它接受一个参数并返回true,false或nil。
  3. 一个函数,它接受一个参数并返回truthey或falsey值。

Jira Ticket on what Predicate is

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

+0

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

回答

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 

对于defenition NR。 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 

一个有趣的事情,我们则似乎是能够做的是有规范产生这样的功能我们:

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

进出,我们或许可以尝试猜测生成的函数做什么。但是,如果我们无法看到源头,就很难检查我们的猜测是否正确。

+0

我的印象是否正确,您发布了您立即回答(而不是第一次)的问题?你的答案已经发布了与你的问题相同的秒... –

+0

@PiotrekBzdyl是的。当你问一个关于SO的问题时,你可以选择自己回答这个问题的问答风格,就像它写的那样。 – Rovanion

+0

是的,我知道一旦你找到解决方案,你可以回答你自己的问题。这是我第一次看到有人使用SO作为一种博客来同时记录问题和答案(因此,这不是发布问题,所以有人可以帮助回答 - 包括问问的人)和这就是为什么我很困惑。 –

1

我想了谓词最准确的规范是:

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

尽管断言通常会返回真/假,没有要求他们这样做的 - 唯一需要的合同是,它需要一个值并返回一个将被视为逻辑真值的值。