2

同じ引数 (A: juxt) を持つ複数の関数をマップする関数についての質問に答える際に、基本的に juxt と同じ形式をとるが、map を使用する関数を思いつきました。

(defn could-be-lazy-juxt
  [& funs]
  (fn [& args]
    (map apply funs (repeat args))))

=> ((juxt inc dec str) 1)
[2 0 "1"]
=> ((could-be-lazy-juxt inc dec str) 1)
(2 0 "1")

=> ((juxt * / -) 6 2)
[12 3 4]
=> ((could-be-lazy-juxt * / -) 6 2)
(12 3 4)

その怠惰やパフォーマンスについてはほとんど手がかりがありませんが、REPL のタイミングは、何か怠惰なことが起こっていることを示唆しています。

=> (time (apply (juxt + -) (range 1 100)))
"Elapsed time: 0.097198 msecs"
[4950 -4948]
=> (time (apply (could-be-lazy-juxt + -) (range 1 100)))
"Elapsed time: 0.074558 msecs"
(4950 -4948)

=> (time (apply (juxt + -) (range 10000000)))
"Elapsed time: 1019.317913 msecs"
[49999995000000 -49999995000000]
=> (time (apply (could-be-lazy-juxt + -) (range 10000000)))
"Elapsed time: 0.070332 msecs"
(49999995000000 -49999995000000)

この関数は実際にはそれほど高速ではないと確信しています (結果の出力は、どちらも同じくらい長く感じます)。関数で「take x」を実行すると、評価される関数の量が制限されるだけであり、おそらくその適用性が制限され、「take」による他のパラメーターの制限は、通常のjuxtと同じように怠惰になるはずです。

このジャクストは本当に怠け者ですか?レイジー ジャクストは、たとえば他のレイジー関数間の合成ステップなど、テーブルに役立つものをもたらしますか? パフォーマンス (メモリ / CPU / オブジェクト数 / コンパイル) への影響は何ですか? Clojure juxt が reduce で実装されてベクトルを返すのはなぜですか?

4

1 に答える 1

1

はい、あなたの juxt の実装は、怠惰な map を呼び出すだけであるため、怠惰です。

呼び出し元の引数を認識せずに現在の形式で呼び出すのは難しいです (apply を使用して)。そのため、関数のシーケンスを取るように少し変更しました。

user> (defn could-be-lazy-juxt
  [funs]
  (fn [& args]
    (map #(apply %1 %2) funs (repeat args))))
#'user/could-be-lazy-juxt

次に、実現したときに多くの出力を生成する関数の遅延シーケンスを定義します

user> (defn loud-seq [len] (take len (map #(do (println "produced a function") %) (cycle [inc dec]))))
#'user/loud-seq

次に、juxt を使用して、この遅延関数シーケンスから関数を作成します。

user> (def f (could-be-lazy-juxt (loud-seq 50)))
#'user/f

リストがまだ怠惰であることがわかるように、結果の関数が呼び出されると、関数のリストであることがわかります。

だからそれを呼び出すことができます:

user> (f 1)
(produced a function
produced a function
2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 produced a function
produced a function
0 2 0)
user> 

そうする理由はあなた次第です;)

于 2012-04-06T23:12:58.153 に答える