我想写一个关于函数作为谓词的含义的规范。关于Clojure世界中的谓词似乎有三种方法,尽管大多数人似乎都认为它们应该以问号结尾。
Jira Ticket on what Predicate is
编辑:谓词也可以采用多个参数,例如contains?
。
答案 0 :(得分:3)
我认为谓词最准确的规范是:
(s/fspec :args (s/cat :v any?) :ret any?)
虽然谓词通常返回true / false,但并不要求它们这样做 - 唯一需要的合同是它需要一个值并返回一个值,该值将被视为逻辑真值。
答案 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
我们似乎能够做的一件有趣的事情就是让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"
然而,我们可以尝试猜测生成的函数的作用。但是如果没有能够看到来源,我们将很难检查我们的猜测是否正确。