2009-07-30 79 views

回答

9

你可以使用every?

user=> (every? string? '("hi" 1)) 
false 

这里有every?的文档。

1

every?会问“这个函数是否对每个seq的成员都返回true”,这与我认为你所要求的接近。对every?的改进将采用函数列表,并询问“这个seq的每个成员的所有这些谓词是否正确”。

这是第一次尝试:

(defn andmap? [data tests] 
    (every? true? (for [d data, f tests] 
        (f d)))) 

user> (andmap? '(2 4 8) [even? pos?]) 
true 
user> (andmap? '(2 4 8) [even? odd?]) 
false 
1

我写andmap宏这需要谓词作为参数,并建立一个功能,“环绕的谓词的and”,即

(andmap integer? odd?) 
==> 
(fn [x] (and (integer? x) 
      (odd? x))) 

(它并不扩展到,这个确实是这个,但是它扩展到相当于这个的东西)

这具有shortcuircuts的谓词所以你可以写

(every? (andmap integer? odd?) [1 3 "a string"]) 

没有得到一个运行时异常,你会与Arthurs answer获得优势。

这里是andmap定义:

 
(defmacro andmap 
    ([]  `(fn [& x#] true)) 
    ([p & ps] `(fn [& x#] (and (apply ~p x#) 
          (apply (andmap [email protected]) x#))))) 

也可以定义andmap作为函数在其上的谓词也短路由于lazyness:

 
(defn andmap [& ps] 
    (fn [& x] 
    (every? true? (map (fn [p] (apply p x)) ps)))) 

的谓词andmap可以接受任意数量的参数,因此可以写入

(map (andmap #(and (integer? %1) 
        (integer? %2)) 
      #(and (odd? %1) 
        (even? %2)) 
      <) 
    [1 3 9] 
    [2 6 "string"]) 

其中评估为(true true false)

2

Clojure 1.3将添加每个pred(以及与“或”版本相关的some-fn)。

clojure.core /每-预解码 ([P] [P1 P2] [P1 P2 P3] [P1 P2 P3 & PS])

采用一组谓词和返回一个函数f,则返回true如果构成谓词的所有 都对其所有参数返回逻辑真值,否则返回 false。请注意,f是短路的,因为它将停止执行第一个参数,该参数会触发原始谓词的逻辑错误结果。

一个幼稚的做法是:

(DEFN每-PRED [& preds(FN [&参数](每一个#(每%参数)preds))?)

但实际实施将会有更好的表现。

相关问题