我正在从 msdn 学习 f# 并查看并尝试 reduce 和 reduce ,我找不到任何区别,签名是相同的
('T -> 'T -> 'T) -> 'T list -> 'T
并且它们都在空列表上抛出相同的错误,那么为什么有 2 个,应该有一些区别
其他人已经解释了差异 - 他们以不同的顺序减少元素。
对于可以与reduce
or一起使用的大多数操作,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
请查看 MSDN 文档,reduce和reduceBack。
因为reduce
它指定:
如果输入函数是 f 并且元素是 i0...iN,那么它计算 f (... (f i0 i1) i2 ...) iN。
因为reduceBack
它指定:
如果输入函数为 f 且元素为 i0...iN,则此函数计算 f i0 (...(f iN-1 iN))。
它们的主要区别在于评估顺序。虽然reduce
从第一个元素到最后一个元素,reduceBack
但顺序相反。请注意,当前元素和累加器之间的顺序也颠倒了reduceBack
。
一个示范性的例子可能是:
let last xs = List.reduce (fun _ x -> x) xs
let first xs = List.reduceBack (fun x _ -> x) xs