我正在做Scala 中的函数式编程练习,以implement foldRight on a Stream
.
在开始练习之前,让我展示一下我是如何实现foldLeft
.
def foldLeft[A, B](as: Stream[A])(z: B)(f: (B, A) => B): B = {
def go(bs: Stream[A], acc: B) : B = bs match {
case x #:: xs => go(xs, f(acc, x))
case Stream() => acc
}
}
我的理解是,通过#::
,我正在以尾递归和流式方式执行折叠,即未完全评估尾部。
但是,当我想到如何实现foldRight
时,我想我可以简单地做:
stream.reverse.foldLeft(monoid.zero)(monoid.op)
但是,调用reverse
将导致对流进行全面评估:
scala> val x = Stream(1,2,3)
x: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> x.reverse
res15: scala.collection.immutable.Stream[Int] = Stream(3, 2, 1)
我怎样才能流式实施foldRight
?