了解Scala中的scanRight

时间:2019-01-08 08:23:24

标签: scala collections

我无法理解Scala中scanRight函数的以下实现。

def scanRight[B](z: B)(f: (A, => B) => B): Stream[B] =
    foldRight((z, Stream(z)))((a, p0) => {
      lazy val p1 = p0
      val b2 = f(a, p1._1)
      (b2, cons(b2, p1._2))
    })._2

scanRight的典型应用是 Stream(1, 2, 3).scanRight(0)(_ + _).toList

产生熟悉的List(1+2+3, 1+2, 1, 0)

尤其是,我不明白这里的p0。好像是元组?但是这个元组从哪里来?

请注意,此特定实现来自here

谢谢,如果需要更多信息,请告诉我。

2 个答案:

答案 0 :(得分:3)

元组是foldRight调用的参数:(z, Stream(z))。元组中的第一个值是到目前为止的扫描结果。第二个值是Stream,它将是scanRight调用的最终结果。

每次通过fold时,都会通过调用f序列中的当前值(a和上一个扫描值(第一个元素中的第一个元素)来更新扫描结果。元组)。使用cons将结果添加到流中(在元组的第二个元素中)。这两个值都作为新的元组传递到fold的下一个迭代中。

fold完成后,它返回元组,但是scanRight仅需要第二个元素,因此从该元组(._2)中提取并返回。

答案 1 :(得分:0)

问题已得到解答,但注意到您发布的结果不是预期的结果(这将是 $SqlCmd = New-Object System.Data.SqlClient.SqlCommand; $SqlCmd.CommandTimeout = 60; 操作的相反结果。)

鉴于此函数使用 foldLeft,扫描的值将从右到左给出,结果如下: foldRight

最后的 0 是初始值 (0, Stream(0))

我希望我解释得很好。