5

我正在从 msdn 学习 f# 并查看并尝试 reduce 和 reduce ,我找不到任何区别,签名是相同的

('T -> 'T -> 'T) -> 'T list -> 'T

并且它们都在空列表上抛出相同的错误,那么为什么有 2 个,应该有一些区别

4

3 回答 3

8

其他人已经解释了差异 - 他们以不同的顺序减少元素。

对于可以与reduceor一起使用的大多数操作,reduceBack差异实际上并不重要。用更数学的术语来说,如果您的操作是关联的(例如数字操作、max、min 或 sum 函数、列表连接等),那么两者的行为相同。

您可以很好地看到差异的一个示例是构建一棵树,因为这准确地显示了评估的工作原理:

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))

这是你得到的两棵树(但请注意,如果你将它们展平,那么你会得到相同的列表!)

          reduce        reduceBack
-------------------------------------
tree:       /\              /\
           /\ 3            0 /\
          /\ 2              1 /\
         0  1                2  3
-------------------------------------
flat:    0 1 2 3          0 1 2 3
于 2012-06-11T10:12:55.107 回答
4

请查看 MSDN 文档,reducereduceBack

因为reduce它指定:

如果输入函数是 f 并且元素是 i0...iN,那么它计算 f (... (f i0 i1) i2 ...) iN。

因为reduceBack它指定:

如果输入函数为 f 且元素为 i0...iN,则此函数计算 f i0 (...(f iN-1 iN))。

于 2012-06-11T09:54:51.903 回答
3

它们的主要区别在于评估顺序。虽然reduce从第一个元素到最后一个元素,reduceBack但顺序相反。请注意,当前元素和累加器之间的顺序也颠倒了reduceBack

一个示范性的例子可能是:

let last xs = List.reduce (fun _ x -> x) xs   
let first xs = List.reduceBack (fun x _ -> x) xs
于 2012-06-11T10:11:27.933 回答