47

Reduce は問題なく動作しますが、左折に似ています。右に折りたたむことができる他の形式の reduce はありますか?

4

2 に答える 2

91

clojure 標準ライブラリが左折 (reduce) しか持たない理由は、実際には非常に微妙であり、右折の主な利点を得るほど clojure が怠惰ではないためです。

Haskell のような言語での右折の主な利点は、実際に短絡できることです。foldr (&&) True [False, True, True, True, True]実際に評価されるようにすれば、非常に啓発的です。評価する必要があるのは、and1 つの引数 (最初のFalse) を持つ関数だけです。そこに到達すると、答えがわかり、 を評価する必要はありませんTrue

写真をよく見ると:

ここに画像の説明を入力

概念的には、右折はリストの最後から開始し、前方に移動しますが、実際には、リストの前方から評価を開始することがわかります。

これは、遅延/カリー化された関数と末尾再帰が clojure では得られないメリットをもたらす例です。

ボーナスセクション(興味のある方)

vemv からの推奨に基づいて、Clojure が遅延右折畳みを行うことができないというこの制限を回避するために、Clojure がコア名前空間に新しい関数を追加したことを言及したいと思います。reducedClojure の遅延を可能にするコア名前空間で呼び出される関数がありますreducereduceリストの残りを見ないように指示することで、ショートサーキットに使用できます。たとえば、数のリストを乗算したいが、リストにゼロが含まれることがあると疑う理由があり、ゼロに遭遇したらリストの残りを調べないという特殊なケースとして処理したい場合は、次のように記述できます。次のmultiply-all関数 (reduced最終的な答えが0リストの残りの部分に関係なくあることを示すために を使用していることに注意してください)。

(defn multiply-all [coll]
  (reduce
   (fn [accumulator next-value]
     (if (zero? next-value)
       (reduced 0)
       (* accumulator next-value)))
   1
   coll))

そして、それが短絡していることを証明するために、たまたまゼロを含む数の無限リストを乗算し、実際に次の答えで終了することを確認できます。0

(multiply-all
 (cycle [1 2 3 4 0]))
于 2013-05-28T13:39:10.960 に答える