为什么在Scala中折叠具有以下类型?

时间:2011-08-09 17:18:33

标签: api scala fold higher-order-functions

我正在研究为immutable.Set定义fold的方式。

def fold [A1 >: A] (z: A1)(op: (A1, A1) ⇒ A1): A1 

但foldLeft定义为:

def foldLeft [B] (z: B)(op: (B, A) ⇒ B): B 

对我来说这看起来很奇怪,至少乍一看,因为我期待折叠能够改变它返回的集合的类型,就像foldLeft那样。

我想这是因为foldLeft和foldRight保证了折叠元素的顺序。折叠给出的保证是什么?

2 个答案:

答案 0 :(得分:6)

当您应用foldLeft时,您的起始值将与第一个列表元素结合使用。结果与第二个列表元素组合在一起。这个结果与第三个等等有关。最终,列表已折叠为与起始值相同类型的一个元素。因此,您只需要一些可以通过函数与列表元素组合的类型 对于foldRight,同样适用,但顺序相反。

fold不保证合并完成后的订单。并不保证它只在一个位置开始。折叠可能并行发生。因为您可以具有并行性,所以可以组合任何2个列表元素或返回值 - 这会为类型添加约束。

关于你的评论,你必须看到一个案例,订单有效:假设你使用折叠来连接一个字符列表,你想要一个文本作为结果。如果您的输入为A, B, C,您可能希望保留接收ABC而不是ACB的订单(例如)。
另一方面,如果您只是添加数字,则顺序无关紧要。总结1, 2, 3会使6独立于添加的顺序。在这种情况下,使用fold代替foldLeftfoldRight可能会加快执行速度。

答案 1 :(得分:0)

似乎FoldLeft必须返回B.该方法采用B arg - 这是一个累加器。 A的值用于“向B添加更多”。返回最终累计值。我认为FoldLeft和FoldRight在这方面是一样的。