8

我正在查看为 immutable.Set 定义折叠的方式:

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

然而 foldLeft 被定义为:

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

这对我来说看起来很奇怪,至少乍一看,因为我希望 fold 能够更改它返回的集合的类型,就像 foldLeft 一样。

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

4

2 回答 2

10

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

fold不保证组合中的顺序已完成。而且它不保证它只从一个位置开始。折叠可能同时发生。因为您可以具有并行性,所以要求可以组合任何 2 个列表元素或返回值——这为类型增加了一个约束。

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

于 2011-08-10T18:31:46.883 回答
1

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

于 2011-08-09T21:37:00.830 回答