我在Programming in Scala
书中阅读有关折叠技术的信息并且遇到了这个片段:
def reverseLeft[T](xs:List[T]) = (List[T]() /: xs) {
(y,ys) => ys :: y
}
Run Code Online (Sandbox Code Playgroud)
如您所见,它是使用foldLeft
或/:
运算符完成的.好奇如果我使用它会是什么样子:\
,我想出了这个:
def reverseRight[T](xs:List[T]) = (xs :\ List[T]()) {
(y,ys) => ys ::: List(y)
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,它:::
似乎没有那么快,::
并且具有线性成本,具体取决于操作数列表的大小.不可否认,我没有CS的背景,也没有先前的FP经验.所以我的问题是:
:::
?Apo*_*isp 12
由于标准库中的foldRight
on List
是严格的并且使用线性递归来实现,因此通常应该避免使用它.foldRight的迭代实现如下:
def foldRight[A,B](f: (A, B) => B, z: B, xs: List[A]) =
xs.reverse.foldLeft(z)((x, y) => f(y, x))
Run Code Online (Sandbox Code Playgroud)
foldLeft的递归实现可能是这样的:
def foldLeft[A,B](f: (B, A) => B, z: B, xs: List[A]) =
xs.reverse.foldRight(z)((x, y) => f(y, x))
Run Code Online (Sandbox Code Playgroud)
所以你看,如果两者都是严格的,那么foldRight和foldLeft中的一个或另一个将被实现(概念上无论如何)reverse
.由于列表是使用::
右侧的关联构造的,所以直接的迭代折叠将是foldLeft
,并且foldRight
简单地"反向然后foldLeft".
直觉上,您可能认为这将是foldRight的缓慢实现,因为它将列表折叠两次.但:
foldRight
上面的实现比标准库中的实现更快.