Clojure.core / или частичная функция хорошо работает с первым аргументом, но не со вторым - PullRequest
4 голосов
/ 25 июня 2010

(defn делится [xy] (ноль? (Rem xy)))

  1. ((или (fn [x] (делится x 3)) (fn [x] (делится на 5))) 3)
  2. ((или (fn [x] (делится на 3)) (fn [x] (делится на 5))) 5)

первыйвыражение становится истинным, но не вторым, почему?

  • Кто-нибудь может объяснить, что здесь происходит?

Ответы [ 2 ]

5 голосов
/ 25 июня 2010

Выражение вида (or foo bar) не «склеивает» два предиката в один составной предикат;он возвращает foo, если он правдив, в противном случае bar.В вашем коде, (fn [x] (divisible x 3)), конечно, верно (единственные ложные значения false и nil), так что все это эквивалентно

((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)
2 голосов
/ 25 июня 2010

Кажется, вы думаете, что or каким-то образом объединяет функции, которые он получает в качестве аргументов, но это не так.or может принимать любые значения в качестве аргументов и просто возвращает первое, которое является "правдивым".

Таким образом, (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).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...