“ andmap”に似た機能はありますかclojureで?
-
06-07-2019 - |
質問
リストに一連のテストを適用し、すべてのテストに合格するようにします。 「andmap」に似た機能はありますか? Clojureで?
解決
他のヒント
Clojure 1.3は、すべてのpred(および"または"バージョンの関連するsome-fn)を追加します。
clojure.core / every-pred ([p] [p1 p2] [p1 p2 p3] [p1 p2 p3& ps])
一連の述語を取得し、そのすべてが 述語を構成すると、その引数のすべてに対して論理的な真の値が返されます。 偽。 fは、最初に実行を停止するという点で短絡していることに注意してください。 元の述部に対して論理的に偽の結果をトリガーする引数。
単純な実装は次のようになります。
(defn every-pred [& preds](fn [& args](every?#(every?%args)preds))
しかし、実際の実装はパフォーマンスが向上します。
andmap
を引数として述語を取り、「 and
を述語の周りにラップ」する関数、つまり
(andmap integer? odd?)
==>
(fn [x] (and (integer? x)
(odd? x)))
(これは正確にはに展開されませんが、これと同等のものに展開されます)
これには、述語をショートカットして書くことができるという利点があります
(every? (andmap integer? odd?) [1 3 "a string"])
andmap
の定義は次のとおりです。
(defmacro andmap ([] `(fn [& x#] true)) ([p & ps] `(fn [& x#] (and (apply ~p x#) (apply (andmap ~@ps) x#)))))
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)
と評価されます。
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