Fixes #3091. Review by community.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@21179 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
prokopec 2010-03-15 14:45:33 +00:00
parent 1e2f71e25c
commit 45b1d5ccdf
3 changed files with 75 additions and 0 deletions

View File

@ -612,6 +612,46 @@ self =>
def reduceRightOption[B >: A](op: (A, B) => B): Option[B] =
if (isEmpty) None else Some(reduceRight(op))
/**
* Produces a collection containing cummulative results of applying the operator going left to right.
* $willNotTerminateInf
* $orderDependent
*
* @tparam B the type of the elements in the resulting collection
* @tparam That the actual type of the resulting collection
* @param z the initial value
* @param op the binary operator applied to the intermediate result and the element
* @param bf $bfinfo
* @return collection with intermediate results
*/
def scanLeft[B, That](z: B)(op: (B, A) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val (_, b) = foldLeft(z, bf(repr) += z) { (acc, x) =>
val next = op(acc._1, x)
(next, acc._2 += next)
}
b.result
}
/**
* Produces a collection containing cummulative results of applying the operator going right to left.
* $willNotTerminateInf
* $orderDependent
*
* @tparam B the type of the elements in the resulting collection
* @tparam That the actual type of the resulting collection
* @param z the initial value
* @param op the binary operator applied to the intermediate result and the element
* @param bf $bfinfo
* @return collection with intermediate results
*/
def scanRight[B, That](z: B)(op: (A, B) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val (_, b) = foldRight(z, bf(repr) += z) { (x, acc) =>
val next = op(x, acc._1)
(next, acc._2 += next)
}
b.result
}
/** Sums up the elements of this collection.
*
* @param num an implicit parameter defining a set of numeric operations

18
test/files/pos/scan.scala Normal file
View File

@ -0,0 +1,18 @@
object Test {
def main(args: Array[String]) {
val lst = List(1, 2, 3, 4, 5)
assert(lst.scanLeft(0)(_ + _) == List(0, 1, 3, 6, 10, 15))
assert(lst.scanRight(0)(_ + _) == List(0, 5, 9, 12, 14, 15))
val emp = List[Int]()
assert(emp.scanLeft(0)(_ + _) == List(0))
assert(emp.scanRight(0)(_ + _) == List(0))
}
}

View File

@ -0,0 +1,17 @@
import org.scalacheck._
import Prop._
import Gen._
object Test extends Properties("TraversableLike.scanLeft") {
property("scanLeft") = forAll { (xs: List[Int], z: Int) => {
val sums = xs.scanLeft(z)(_ + _)
(xs.size == 0) || sums.zip(sums.tail).map(x => x._2 - x._1) == xs
}}
}