私は msdn から f# を学んでいて、reduce と reduce back を探して試していますが、違いは見つかりません。署名は同じです
('T -> 'T -> 'T) -> 'T list -> 'T
どちらも空のリストで同じエラーをスローするので、なぜ2つあるのですか、いくつかの違いがあるはずです
他の人はすでに違いを説明しています-それらは要素を異なる順序で削減します。
reduce
またはで使用できる操作のほとんどではreduceBack
、違いは実際には問題になりません。より数学的に言えば、演算が連想的である場合(数値演算、max、min、または sum 関数、リスト連結など)、2 つの動作は同じになります。
違いがよくわかる例は、ツリーの構築です。これは、評価がどのように機能するかを正確に示しているためです。
type Tree =
| Leaf of int
| Node of Tree * Tree
[ for n in 0 .. 3 -> Leaf n]
|> List.reduce (fun a b -> Node(a, b))
[ for n in 0 .. 3 -> Leaf n]
|> List.reduceBack (fun a b -> Node(a, b))
結果として得られる 2 つのツリーを次に示します (ただし、それらを平坦化すると、同じリストが得られることに注意してください!)
reduce reduceBack
-------------------------------------
tree: /\ /\
/\ 3 0 /\
/\ 2 1 /\
0 1 2 3
-------------------------------------
flat: 0 1 2 3 0 1 2 3
MSDN ドキュメントのreduceおよびreduceBackを参照してください。
それは次のreduce
ことを指定するためです。
入力関数が f で要素が i0...iN の場合、f (... (f i0 i1) i2 ...) iN を計算します。
それは次のreduceBack
ことを指定するためです。
入力関数が f で要素が i0...iN の場合、この関数は f i0 (...(f iN-1 iN)) を計算します。
主な違いは評価の順序です。whilereduce
は最初の要素から最後の要素にreduceBack
移動し、逆の順序で移動します。では、現在の要素とアキュムレータの間の順序も逆になっていることに注意してくださいreduceBack
。
実例は次のとおりです。
let last xs = List.reduce (fun _ x -> x) xs
let first xs = List.reduceBack (fun x _ -> x) xs