summaryrefslogtreecommitdiff
path: root/src/library/scala/collection/immutable/Stream.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-03-11 12:13:58 +0000
committerPaul Phillips <paulp@improving.org>2011-03-11 12:13:58 +0000
commitbe49752855a1a6997d4112eeff351e1c119a8a93 (patch)
treeee2cef3642b675420d47ff30bda9ddb2b74f1c30 /src/library/scala/collection/immutable/Stream.scala
parent67c461b2d9c19d51e40e1f3ff23455cead1413b5 (diff)
downloadscala-be49752855a1a6997d4112eeff351e1c119a8a93.tar.gz
scala-be49752855a1a6997d4112eeff351e1c119a8a93.tar.bz2
scala-be49752855a1a6997d4112eeff351e1c119a8a93.zip
A patch for views. Most relevant change:
Almost all view classes now list parents like trait Appended[B >: A] extends super.Appended[B] with Transformed[B] instead of the former trait Appended[B >: A] extends Transformed[B] with super.Appended[B] because as it was, the implementation of foreach in TraversableViewLike#Transformed was repeatedly trumping overrides found in e.g. IterableLike. This change was not without its own consequences, and much of the rest of the patch is dealing with that. A more general issue is clearly revealed here: there is no straightforward way to deal with trait composition and overrides when some methods should prefer B over A and some the reverse. (It's more like A through Z in this case.) That closes #4279, with some views being five orders of magnitude slower than necessary. There is a test that confirms they'll stay performance neighbors. In the view classes (Zipped, Mapped, etc.) I attended to them with comb and brush until they were reasonably consistent. I only use "override" where necessary and throw in some "final" in the interests of trying to anchor the composition outcome. I also switched the newSliced, newZipped, etc. methods to use early init syntax since a number have abstract vals and I found at least one bug originating with uninitialized access. There was a piece of a parallel collections scalacheck test failing, which I disabled out of expedience - am emailing prokopec. There is plenty of work left to do but paulp must get back to other 2.9 issues. This is the Zurich->SF airplane patch. No review.
Diffstat (limited to 'src/library/scala/collection/immutable/Stream.scala')
-rw-r--r--src/library/scala/collection/immutable/Stream.scala81
1 files changed, 38 insertions, 43 deletions
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index b12b312d21..2a4c29c05e 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -269,33 +269,8 @@ self =>
new StreamWithFilter(x => p(x) && q(x))
}
- /** See #3273 and test case run/bug3273 for motivation. */
- final class StreamIterator extends Iterator[A] {
- // A call-by-need cell.
- class LazyCell(st: => Stream[A]) {
- lazy val v = st
- }
-
- private var these = new LazyCell(self)
- def hasNext: Boolean = these.v.nonEmpty
- def next: A =
- if (isEmpty) Iterator.empty.next
- else {
- val cur = these.v
- val result = cur.head
- these = new LazyCell(cur.tail)
- result
- }
- override def toStream = {
- val result = these.v
- these = new LazyCell(Stream.empty)
- result
- }
- override def toList = toStream.toList
- }
-
/** A lazier Iterator than LinearSeqLike's. */
- override def iterator: Iterator[A] = new StreamIterator
+ override def iterator: Iterator[A] = new StreamIterator(self)
/** Apply the given function <code>f</code> to each element of this linear sequence
* (while respecting the order of the elements).
@@ -392,21 +367,12 @@ self =>
b
}
+ override def mkString(sep: String): String = mkString("", sep, "")
+ override def mkString: String = mkString("")
override def mkString(start: String, sep: String, end: String): String = {
this.force
super.mkString(start, sep, end)
}
-
- override def mkString(sep: String): String = {
- this.force
- super.mkString(sep)
- }
-
- override def mkString: String = {
- this.force
- super.mkString
- }
-
override def toString = super.mkString(stringPrefix + "(", ", ", ")")
override def splitAt(n: Int): (Stream[A], Stream[A]) = (take(n), drop(n))
@@ -422,6 +388,10 @@ self =>
else if (n == 1) cons(head, Stream.empty)
else cons(head, tail take n-1)
+ @tailrec final override def drop(n: Int): Stream[A] =
+ if (n <= 0 || isEmpty) this
+ else tail drop n-1
+
/** A substream starting at index `from` and extending up to (but not including)
* index `until`.
*
@@ -534,6 +504,31 @@ self =>
}
+/** See #3273 and test case run/bug3273 for motivation. */
+final class StreamIterator[+A](self: Stream[A]) extends Iterator[A] {
+ // A call-by-need cell.
+ class LazyCell(st: => Stream[A]) {
+ lazy val v = st
+ }
+
+ private var these = new LazyCell(self)
+ def hasNext: Boolean = these.v.nonEmpty
+ def next: A =
+ if (isEmpty) Iterator.empty.next
+ else {
+ val cur = these.v
+ val result = cur.head
+ these = new LazyCell(cur.tail)
+ result
+ }
+ override def toStream = {
+ val result = these.v
+ these = new LazyCell(Stream.empty)
+ result
+ }
+ override def toList = toStream.toList
+}
+
/**
* The object <code>Stream</code> provides helper functions
* to manipulate streams.
@@ -644,7 +639,7 @@ object Stream extends SeqFactory[Stream] {
* @param f the function that's repeatedly applied
* @return the stream returning the infinite sequence of values `start, f(start), f(f(start)), ...`
*/
- def iterate[A](start: A)(f: A => A): Stream[A] = new Cons(start, iterate(f(start))(f))
+ def iterate[A](start: A)(f: A => A): Stream[A] = cons(start, iterate(f(start))(f))
override def iterate[A](start: A, len: Int)(f: A => A): Stream[A] =
iterate(start)(f) take len
@@ -658,7 +653,7 @@ object Stream extends SeqFactory[Stream] {
* @return the stream starting at value <code>start</code>.
*/
def from(start: Int, step: Int): Stream[Int] =
- new Cons(start, from(start+step, step))
+ cons(start, from(start+step, step))
/**
* Create an infinite stream starting at <code>start</code>
@@ -676,14 +671,14 @@ object Stream extends SeqFactory[Stream] {
* @param elem the element composing the resulting stream
* @return the stream containing an infinite number of elem
*/
- def continually[A](elem: => A): Stream[A] = new Cons(elem, continually(elem))
+ def continually[A](elem: => A): Stream[A] = cons(elem, continually(elem))
override def fill[A](n: Int)(elem: => A): Stream[A] =
- if (n <= 0) Empty else new Cons(elem, fill(n-1)(elem))
+ if (n <= 0) Empty else cons(elem, fill(n-1)(elem))
override def tabulate[A](n: Int)(f: Int => A): Stream[A] = {
def loop(i: Int): Stream[A] =
- if (i >= n) Empty else new Cons(f(i), loop(i+1))
+ if (i >= n) Empty else cons(f(i), loop(i+1))
loop(0)
}
@@ -692,7 +687,7 @@ object Stream extends SeqFactory[Stream] {
import num._
if (if (step < zero) start <= end else end <= start) Empty
- else new Cons(start, range(start + step, end, step))
+ else cons(start, range(start + step, end, step))
}
private[immutable] def filteredTail[A](stream: Stream[A], p: A => Boolean) = {