clojure.core /或partial函数适用于第一个参数但不适用于第二个参数

时间:2010-06-25 19:04:04

标签: clojure

(defn divisible [x y](零?(rem x y)))

  1. ((或(fn [x](可分割x 3))(fn [x](可分x 5)))3)
  2. ((或(fn [x](可分割x 3))(fn [x](可分×5)))5)
  3. 第一个表达式是eval为true而不是第二个为什么?

    • 有人可以解释一下这里发生了什么吗?

2 个答案:

答案 0 :(得分:5)

(or foo bar)形式的表达式不会将两个谓词“粘合”成一个复合谓词;如果它是真实的,则返回foo,否则bar。在您的代码中,(fn [x] (divisible x 3))当然是真实的(唯一的假值是falsenil),所以整个事情等同于

((fn [x] (divisible x 3)) 3)
((fn [x] (divisible x 3)) 5)

你想做的事情就像是

(some #(apply % 3) [(fn [x] (divisible x 3)) (fn [x] (divisible x 5)])
(some #(apply % 5) [(fn [x] (divisible x 3)) (fn [x] (divisible x 5)])
              ; ^- here goes the thing being tested

一般来说,

(defn or-preds [& preds]
  (fn [& args]
    (some #(apply % args) preds)))

((or-preds (fn [x] (divisible x 3)) (fn [x] (divisible x 5))) 3)
((or-preds (fn [x] (divisible x 3)) (fn [x] (divisible x 5))) 5)
;; or simpler...
((or-preds #(divisible % 3) #(divisible % 5)) 3)

答案 1 :(得分:2)

您似乎认为or以某种方式将它接收的函数组合为参数,但事实并非如此。 or可以将任何类型的值作为参数,只返回第一个“truthy”。

所以(or (fn [x] (divisible x 3)) (fn [x] (divisible x 5)))返回(fn [x] (divisible x 3))(因为函数“不是什么都没有”,因此“真实”)。

所以当你((or (fn [x] (divisible x 3)) (fn [x] (divisible x 5))) something)时,你真的只是做((fn [x] (divisible x 3)) something)