2009-07-30 57 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))?)

但實際實施將會有更好的表現。

相關問題