【问题标题】:Why does fold have the following type in Scala?为什么 fold 在 Scala 中具有以下类型?
【发布时间】:2011-08-09 17:18:32
【问题描述】:

我正在查看为 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 给的保证是什么?

【问题讨论】:

  • 让-菲利普的回答对您有帮助吗?见stackoverflow.com/questions/6253978/…
  • 在某种程度上,我猜。我还没有看到 fold 会在集合 API 中返回与 foldLeft 不同的结果的情况,但我想可能存在一些需要这种区别的实现。感谢您的链接。

标签: api scala fold higher-order-functions


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢。我认为顺序很重要,但我从未考虑过并行性。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 2015-02-10
    • 1970-01-01
    • 2011-07-16
    相关资源
    最近更新 更多