.net reduce和reduceBack之间有什么区别吗
我正在从msdn学习f#并查看和尝试reduce和reduce back,我找不到任何区别,签名是相同的.net reduce和reduceBack之间有什么区别吗,.net,f#,.net,F#,我正在从msdn学习f#并查看和尝试reduce和reduce back,我找不到任何区别,签名是相同的 ('T->'T->'T)->'T list->'T 它们都会在空列表上抛出相同的错误,那么为什么有两个呢,应该有一些不同请查看MSDN文档,然后 对于reduce,它指定: 如果输入函数为f,元素为i0…iN,则 在中计算f(…(f i0 i1)i2…) 对于reduceBack,它指定: 如果输入函数是f,元素是i0…iN,那么 函数计算f i0(…(f iN-1 iN)) 它们的主要区别
('T->'T->'T)->'T list->'T
它们都会在空列表上抛出相同的错误,那么为什么有两个呢,应该有一些不同请查看MSDN文档,然后 对于
reduce
,它指定:
如果输入函数为f,元素为i0…iN,则
在中计算f(…(f i0 i1)i2…)
对于reduceBack
,它指定:
如果输入函数是f,元素是i0…iN,那么
函数计算f i0(…(f iN-1 iN))
它们的主要区别在于评价顺序。当
reduce
从第一个元素到最后一个元素时,reduceBack
的顺序相反。请注意,当前元素和累加器之间的顺序在还原回退中也是颠倒的
一个示例可以是:
let last xs = List.reduce (fun _ x -> x) xs
let first xs = List.reduceBack (fun x _ -> x) xs
其他人已经解释了差异——他们以不同的顺序减少元素
对于可以与reduce
或reduceBack
一起使用的大多数操作,差异实际上并不重要。用更数学的术语来说,如果您的操作是(如数值操作、最大、最小或求和函数、列表串联等),那么这两种操作的行为是相同的
您可以很好地看到差异的一个示例是构建一棵树,因为这正好显示了评估的工作方式:
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))
下面是您得到的两棵树(但请注意,如果您将它们展平,则会得到相同的列表!)
我怀疑它决定了还原是发生在左侧还是右侧。我不知道f#,但可能是不同的。在msdn上,它没有说任何关于左/右的内容,因为reduce它说它首先在前2个上应用reduce func,对于reduceBack,虽然没有这样说,但它仍然有效same@phgf#中有一个折叠函数,仅用于that@phg正确,另请参见折叠/折叠(左折叠和右折叠)。您知道这些符号中的s
代表什么吗,例如,对于折叠,有fi0(…(f in s))
,什么是s
如果我理解正确,s
是foldBack
案例中的初始状态。如果你看下面的例子,我认为应该更清楚。
reduce reduceBack
-------------------------------------
tree: /\ /\
/\ 3 0 /\
/\ 2 1 /\
0 1 2 3
-------------------------------------
flat: 0 1 2 3 0 1 2 3