2009-07-30 8 views

答えて

9

あなたはevery?を使用することができます。

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

はここevery?のドキュメントです。

1

every?「この1つの関数は、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 integer? odd?) 
==> 
(fn [x] (and (integer? x) 
      (odd? x))) 
、すなわち、その引数として述語を取り、「述語の周り andをラップ」という機能を構築するマクロとして andmapを書きました

(これはに正確にはに拡張されませんが、これに相当するものに展開されます)

これは、あなたがArthurs answerになるだろうと実行時例外を取得せずに

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

を書くことができますので、それは述語にshortcuircuts利点を持っています。ここで

andmapの定義です:

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

原因lazynessへの述語に機能も短絡としてandmapを定義することも可能である:

 
(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はevery-pred(および "or"バージョンの関連するsome-fn)を追加します。

clojure.core /毎-predを ([P] [P1とP2] [P1 P2 P3] [P1 P2 P3 & PS])

は真を返す関数fを述語の集合を受け取り、返しその述語を構成している 述語のすべてがそのすべての引数に対して論理真の値を返した場合は、 falseを返します。 fは、最初の 引数の実行を停止し、元の述部に対して論理偽の結果をトリガーする点で短絡していることに注意してください。

ナイーブな実装では、かもしれない:

(DEFN毎-predを[& preds(FN [&引数](毎#(すべての%引数)preds))?)

実際実装のパフォーマンスが向上します。

関連する問題