From 54b5eacb56d21664e53b92d1e5c58195538caef4 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 20 Sep 2010 03:47:39 +0000 Subject: Tail recursive implementation of mapConserve, s... Tail recursive implementation of mapConserve, submitted by Eric Willigers. Closes #2411, review by malayeri. --- test/files/run/mapConserve.scala | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 test/files/run/mapConserve.scala (limited to 'test/files/run') diff --git a/test/files/run/mapConserve.scala b/test/files/run/mapConserve.scala new file mode 100644 index 0000000000..a285113b11 --- /dev/null +++ b/test/files/run/mapConserve.scala @@ -0,0 +1,53 @@ +import scala.annotation.tailrec +import scala.collection.mutable.ListBuffer + +object Test { + val maxListLength = 7 // up to 16, but larger is slower + var testCount = 0 + + def checkStackOverflow() = { + var xs: List[String] = Nil + for (i <- 0 until 250000) + xs = "X" :: xs + + val lowers = xs.mapConserve(_.toLowerCase) + assert(xs.mapConserve(x => x) eq xs) + } + + def checkBehaviourUnchanged(input: List[_], oldOutput: List[_], newOutput: List[_]) { + if (oldOutput eq input) + assert(newOutput eq oldOutput) + else { + assert(newOutput.head == oldOutput.head) + checkBehaviourUnchanged(input.tail, oldOutput.tail, newOutput.tail) + } + testCount += 1 + } + + var callCount = 0 + val lastHexDigit: Function1[BigInt, AnyRef] = { x: BigInt => callCount+=1; if (x < 16) x else x % 16 } + + def main(args: Array[String]) { + for (length <- 0 to maxListLength; + bitmap <- 0 until (1 << length); + data = List.range(0, length) map { x: Int => + if ((bitmap & (1 << x)) != 0) BigInt(x+16) + else BigInt(x) + }) + { + // Behaves like map with respect to == + callCount = 0 + val numUnconserved = data.reverse.dropWhile(_ < 16).length + val result = data mapConserve lastHexDigit + val mapResult = data map lastHexDigit + assert(result == mapResult) + assert((result drop numUnconserved) eq (data drop numUnconserved)) + assert(callCount == 2 * length) // map, mapConserve call transform for each element in the list + + // Behaves like existing mapConserve with respect to eq + checkBehaviourUnchanged(data, data mapConserve lastHexDigit, data mapConserve lastHexDigit) + } + + checkStackOverflow(); + } +} \ No newline at end of file -- cgit v1.2.3