如何在Scala中将fold
实现为for-comprehension
?我看到唯一的方法是使用一些递归调用?这是一个失败的尝试,不知道如何做到这一点?将fold
作为for-comprehension
val nums = List(1,2,3)
nums.fold(0)(_+_)
def recFold(acc: Int = 0): Int = {
(for {
a <- nums
b = recFold(a + acc)
} yield b).head
}
recFold(0) //Stack overflow
答案 0 :(得分:2)
如果你真的想使用for
,你不需要递归,但你需要一个可变变量:
val nums = List(1,2,3)
def recFold(zero: Int)(op: (Int, Int) => Int): Int = {
var result: Int = zero
for { a <- nums } result = op(result, a)
result
}
recFold(0)(_ + _) // 6
这与foldLeft
中实际TraversableOnce
的实施方式非常相似:
def foldLeft[B](z: B)(op: (B, A) => B): B = {
var result = z
this foreach (x => result = op(result, x))
result
}
答案 1 :(得分:0)
折叠可以从右到左,从左到右实现。无需使用for
加递归。递归就足够了。
def foldRight[A, B](as: List[A], z: B)(f: (A, B) => B): B = {
as match {
case Nil => z
case x :: xs => f(x, foldRight(xs, z)(f))
}
}
@annotation.tailrec
def foldLeft[A, B](as: List[A], z: B)(f: (A, B) => B): B = {
as match {
case Nil => z
case x :: xs => foldLeft(xs, f(x, z))(f)
}
}