Clojure 谓词集合的短路真值检验
假设需要检查参数是否通过给定谓词集合的一个真值测试 代码方面:Clojure 谓词集合的短路真值检验,clojure,Clojure,假设需要检查参数是否通过给定谓词集合的一个真值测试 代码方面: (fn [x] (or (pred1 x) (pred2 x) (pred3 x) (pred4 x))) 由于执行了或,这会在第一个真值之后短路。如预期的那样 如何通过使用一组谓词来重写: [pred1 pred2 pred3 pred4] 一种时髦的方式是: (fn [x preds] (some? ;; nil->false (some
(fn [x]
(or (pred1 x) (pred2 x) (pred3 x) (pred4 x)))
由于执行了或,这会在第一个真值之后短路。如预期的那样
如何通过使用一组谓词来重写:
[pred1 pred2 pred3 pred4]
一种时髦的方式是:
(fn [x preds]
(some? ;; nil->false
(some true? (map #(% x) preds))))
它也证明了这个不会短路。可能是由于Clojure对惰性序列的分块
我们能做得更好吗?当我需要短路时,我使用reduce with reduced
(defn any-valid? [w & pred-fn-coll]
(reduce (fn [v pf]
(if (pf w)
(reduced true)
v)) false pred-fn-coll))
(any-valid? 1 even? odd?)
;=> true
(any-valid? 1 even? even?)
;=> false
当我需要短路时,我使用reduce和reduce
(defn any-valid? [w & pred-fn-coll]
(reduce (fn [v pf]
(if (pf w)
(reduced true)
v)) false pred-fn-coll))
(any-valid? 1 even? odd?)
;=> true
(any-valid? 1 even? even?)
;=> false
我认为是map
在解决方案中进行分块
试一试
最后一个示例表明,计算是惰性的 我认为是map
在解决方案中进行分块
试一试
最后一个示例表明,计算是惰性的 clojure有一个一些fn
功能:
user> ((some-fn true? false? nil?) true)
true
user> ((some-fn false? nil?) true)
false
或者对于您的情况:
user> (defn any-pred? [x preds]
((apply some-fn preds) x))
另一个经典方法是递归执行:
user> (defn any-pred? [x preds]
(when-let [[pred & preds] (seq preds)]
(or (pred x) (any-pred? x preds))))
user> (any-pred? true [false?])
nil
user> (any-pred? true [true?])
true
user> (any-pred? true [false? true?])
true
user> (any-pred? true [false? nil?])
nil
user> (any-pred? true [false? nil? true?])
true
clojure有一个一些fn
功能:
user> ((some-fn true? false? nil?) true)
true
user> ((some-fn false? nil?) true)
false
或者对于您的情况:
user> (defn any-pred? [x preds]
((apply some-fn preds) x))
另一个经典方法是递归执行:
user> (defn any-pred? [x preds]
(when-let [[pred & preds] (seq preds)]
(or (pred x) (any-pred? x preds))))
user> (any-pred? true [false?])
nil
user> (any-pred? true [true?])
true
user> (any-pred? true [false? true?])
true
user> (any-pred? true [false? nil?])
nil
user> (any-pred? true [false? nil? true?])
true
或者
(defn somep? [x [p & ps :as preds]]
(if-not (empty? preds)
(or (p x) (somep? x ps))))
或
或者
(defn somep? [x [p & ps :as preds]]
(if-not (empty? preds)
(or (p x) (somep? x ps))))
或
比使用显式递归更好。比使用显式递归更好。你的第一个选择可能是(defn somep?[x[p&ps:as preds]](when(seq preds)(或(px)(recur x ps)))
。你的第一个选择可能是(defn somep?[x[p&ps:as preds]](when(seq preds)(或(px)(recur x ps)))
。