3

私はこのClojureコードを持っています:

(defn apply-all-to-arg [& s]
    (let [arg (first s)
          exprs (rest s)]
        (for [condition exprs] (condition arg))))

(defn true-to-all? [& s]
    (every? true? (apply-all-to-arg s)))

これはテストコードです:

(apply-all-to-arg 2 integer? odd? even?)

=> (真偽真)

(every? true? (apply-all-to-arg 2 integer? odd? even?)

=>偽

(true-to-all? 2 integer? odd? even?)

=>真

私の質問は次のとおりです。なぜ関数はすべてに忠実なのですか? true を返す (代わりに false を返す必要があります)

4

4 に答える 4

3

true-to-all?apply-all-to-arg単一の引数で呼び出しますs。したがって、 を呼び出しているのではなく(every? true? (apply-all-to-arg 2 integer? odd? even?)、次のように呼び出しています。

(every? true? (apply-all-to-arg (list 2 integer? odd? even?))

したがって、apply-all-to-argの値はargそのリストになり、の値はexprs空のリストになります。every?条件が何であれ、空のリストに対して true になるため、true が返されます。

これを修正するapply-all-to-argには、可変数の引数の代わりにリストを受け入れるように を変更するか、単一のリストではなく複数の引数として ( を使用して)true-to-all?の内容を渡すように を変更することができます。sapply

于 2012-08-25T06:54:56.530 に答える
2

複数の関数を 1 つの引数に並列に適用する関数を作成するデフォルトの Clojure 関数は juxt です。

=> ((juxt integer? odd? even?) 2)
[true false true]

=> (every? true? ((juxt integer? odd? even?) 2))
false

=> (defn true-to-all? [a & fns]
     (every? true? ((apply juxt fns) a)))

=> (true-to-all? 2 integer? odd? even?)
false

juxt と組み合わせる関数がすべて複数の引数を取る場合も同様に機能します

=> ((juxt + - / *) 6 3)
[9 3 2 18]
于 2012-08-25T11:26:57.860 に答える
0

以下のように関数を定義して、より明確にすることもできます。

(defn apply-all-to-arg [v & fns] 
       (map #(% v) fns))

これにより、値とその値に適用するオプションの関数が必要であることを関数定義が明確にするためです。

于 2012-08-25T07:20:22.380 に答える
0

を呼び出すときtrue-to-all?、パラメーターsはリストであるため、効果的に呼び出しているためです(apply-all-to-arg '(2 integer? odd? even?))

true-to-all?次のように定義してみてください。

(defn true-to-all? [& s]
  (every? true? (apply apply-all-to-arg s))
于 2012-08-25T06:58:20.657 に答える