summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-07-14 15:35:07 +0000
committerMartin Odersky <odersky@gmail.com>2009-07-14 15:35:07 +0000
commit0be42af7a28a92739712636289009f3996370388 (patch)
tree16a35a681c97dba957cb6036c95874897fd82109
parentac779096c1c2c6e3e1d563855bfc20fb76b04746 (diff)
downloadscala-0be42af7a28a92739712636289009f3996370388.tar.gz
scala-0be42af7a28a92739712636289009f3996370388.tar.bz2
scala-0be42af7a28a92739712636289009f3996370388.zip
made streams and views more lazy by always skip...
made streams and views more lazy by always skipping builder
-rw-r--r--src/library/scala/collection/generic/SequenceViewTemplate.scala14
-rw-r--r--src/library/scala/collection/generic/TraversableViewTemplate.scala27
-rw-r--r--src/library/scala/collection/immutable/Stream.scala35
3 files changed, 50 insertions, 26 deletions
diff --git a/src/library/scala/collection/generic/SequenceViewTemplate.scala b/src/library/scala/collection/generic/SequenceViewTemplate.scala
index 4fb918628d..998b61271a 100644
--- a/src/library/scala/collection/generic/SequenceViewTemplate.scala
+++ b/src/library/scala/collection/generic/SequenceViewTemplate.scala
@@ -151,18 +151,20 @@ trait SequenceViewTemplate[+A,
override def reverse: This = newReversed.asInstanceOf[This]
override def patch[B >: A, That](from: Int, patch: Sequence[B], replaced: Int)(implicit bf: BuilderFactory[B, That, This]): That = {
- val b = bf(thisCollection)
- if (b.isInstanceOf[NoBuilder[_]]) newPatched(from, patch, replaced).asInstanceOf[That]
- else super.patch[B, That](from, patch, replaced)(bf)
+ newPatched(from, patch, replaced).asInstanceOf[That]
+// was: val b = bf(thisCollection)
+// if (b.isInstanceOf[NoBuilder[_]]) newPatched(from, patch, replaced).asInstanceOf[That]
+// else super.patch[B, That](from, patch, replaced)(bf)
}
override def padTo[B >: A, That](len: Int, elem: B)(implicit bf: BuilderFactory[B, That, This]): That =
patch(length, fill(len - length)(elem), 0)
override def zip[A1 >: A, B, That](that: Sequence[B])(implicit bf: BuilderFactory[(A1, B), That, This]): That = {
- val b = bf(thisCollection)
- if (b.isInstanceOf[NoBuilder[_]]) newZipped(that).asInstanceOf[That]
- else super.zip[A1, B, That](that)(bf)
+ newZipped(that).asInstanceOf[That]
+// was: val b = bf(thisCollection)
+// if (b.isInstanceOf[NoBuilder[_]]) newZipped(that).asInstanceOf[That]
+// else super.zip[A1, B, That](that)(bf)
}
override def zipWithIndex[A1 >: A, That](implicit bf: BuilderFactory[(A1, Int), That, This]): That =
diff --git a/src/library/scala/collection/generic/TraversableViewTemplate.scala b/src/library/scala/collection/generic/TraversableViewTemplate.scala
index 9ea1f6d2fc..84d5b9d0b3 100644
--- a/src/library/scala/collection/generic/TraversableViewTemplate.scala
+++ b/src/library/scala/collection/generic/TraversableViewTemplate.scala
@@ -19,6 +19,12 @@ import TraversableView.NoBuilder
* target="contentFrame"><code>Traversable</code></a>.<br/>
* Every subclass has to implement the <code>foreach</code> method.
* </p>
+ * @note Methods such as map/flatMap on this will not invoke the implicitly passed
+ * Builder factory, but will return a new view directly, to preserve by-name behavior.
+ * The new view is then cast to the factory's result type.
+ * This means that every BuilderFactory that takes a
+ * View as its From type parameter must yield the same view (or a generic superclass of it)
+ * as its result parameter. If that assumption is broken, cast errors might result.
*
* @author Martin Odersky
* @version 2.8
@@ -136,23 +142,26 @@ self =>
protected def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p }
override def ++[B >: A, That](that: Traversable[B])(implicit bf: BuilderFactory[B, That, This]): That = {
- val b = bf(thisCollection)
- if (b.isInstanceOf[NoBuilder[_]]) newAppended(that).asInstanceOf[That]
- else super.++[B, That](that)(bf)
+ newAppended(that).asInstanceOf[That]
+// was: val b = bf(thisCollection)
+// if (b.isInstanceOf[NoBuilder[_]]) newAppended(that).asInstanceOf[That]
+// else super.++[B, That](that)(bf)
}
override def ++[B >: A, That](that: Iterator[B])(implicit bf: BuilderFactory[B, That, This]): That = ++[B, That](that.toStream)
override def map[B, That](f: A => B)(implicit bf: BuilderFactory[B, That, This]): That = {
- val b = bf(thisCollection)
- if (b.isInstanceOf[NoBuilder[_]]) newMapped(f).asInstanceOf[That]
- else super.map[B, That](f)(bf)
+ newMapped(f).asInstanceOf[That]
+// was: val b = bf(thisCollection)
+// if (b.isInstanceOf[NoBuilder[_]]) newMapped(f).asInstanceOf[That]
+// else super.map[B, That](f)(bf)
}
override def flatMap[B, That](f: A => Traversable[B])(implicit bf: BuilderFactory[B, That, This]): That = {
- val b = bf(thisCollection)
- if (b.isInstanceOf[NoBuilder[_]]) newFlatMapped(f).asInstanceOf[That]
- else super.flatMap[B, That](f)(bf)
+ newFlatMapped(f).asInstanceOf[That]
+// was: val b = bf(thisCollection)
+// if (b.isInstanceOf[NoBuilder[_]]) newFlatMapped(f).asInstanceOf[That]
+// else super.flatMap[B, That](f)(bf)
}
override def filter(p: A => Boolean): This = newFiltered(p).asInstanceOf[This]
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index 523fda9465..9f609796f5 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -117,8 +117,9 @@ self =>
override def ++[B >: A, That](that: Traversable[B])(implicit bf: BuilderFactory[B, That, Stream[A]]): That = {
def loop(these: Stream[A]): Stream[B] =
if (these.isEmpty) that.toStream else new Stream.Cons(these.head, loop(these.tail))
- if (bf.isInstanceOf[Stream.StreamBuilderFactory[_]]) loop(this).asInstanceOf[That]
- else super.++(that)
+ loop(this).asInstanceOf[That]
+// was: if (bf.isInstanceOf[Stream.StreamBuilderFactory[_]]) loop(this).asInstanceOf[That]
+// else super.++(that)
}
/** Create a new stream which contains all elements of this stream
@@ -137,8 +138,9 @@ self =>
override def map[B, That](f: A => B)(implicit bf: BuilderFactory[B, That, Stream[A]]): That = {
def loop(these: Stream[A]): Stream[B] =
if (these.isEmpty) Stream.Empty else new Stream.Cons(f(these.head), loop(these.tail))
- if (bf.isInstanceOf[Stream.StreamBuilderFactory[_]]) loop(this).asInstanceOf[That]
- else super.map(f)
+ loop(this).asInstanceOf[That]
+// was: if (bf.isInstanceOf[Stream.StreamBuilderFactory[_]]) loop(this).asInstanceOf[That]
+// else super.map(f)
}
/** Applies the given function <code>f</code> to each element of
@@ -154,10 +156,11 @@ self =>
else {
val seg = f(these.head)
if (seg.isEmpty) loop(these.tail)
- else seg.toStream ++ loop(these.tail)
+ else seg.toStream append loop(these.tail)
}
- if (bf.isInstanceOf[Stream.StreamBuilderFactory[_]]) loop(this).asInstanceOf[That]
- else super.flatMap(f)
+ loop(this).asInstanceOf[That]
+// was: if (bf.isInstanceOf[Stream.StreamBuilderFactory[_]]) loop(this).asInstanceOf[That]
+// else super.flatMap(f)
}
/** Returns all the elements of this stream that satisfy the
@@ -200,8 +203,9 @@ self =>
def loop(these: Stream[A], elems2: Iterator[B]): Stream[(A1, B)] =
if (these.isEmpty || !elems2.hasNext) Stream.Empty
else new Stream.Cons((these.head, elems2.next), loop(these.tail, elems2))
- if (bf.isInstanceOf[Stream.StreamBuilderFactory[_]]) loop(this, that.iterator).asInstanceOf[That]
- else super.zip[A1, B, That](that)
+ loop(this, that.iterator).asInstanceOf[That]
+// was: if (bf.isInstanceOf[Stream.StreamBuilderFactory[_]]) loop(this, that.iterator).asInstanceOf[That]
+// else super.zip[A1, B, That](that)
}
/** Zips this iterable with its indices. `s.zipWithIndex` is equivalent to
@@ -315,8 +319,9 @@ self =>
def loop(len: Int, these: Stream[A]): Stream[B] =
if (these.isEmpty) Stream.fill(len)(elem)
else new Stream.Cons(these.head, loop(len - 1, these.tail))
- if (bf.isInstanceOf[Stream.StreamBuilderFactory[_]]) loop(len, this).asInstanceOf[That]
- else super.padTo(len, elem)
+ loop(len, this).asInstanceOf[That]
+// was: if (bf.isInstanceOf[Stream.StreamBuilderFactory[_]]) loop(len, this).asInstanceOf[That]
+// else super.padTo(len, elem)
}
/** A list consisting of all elements of this list in reverse order.
@@ -347,6 +352,14 @@ self =>
*/
object Stream extends SequenceFactory[Stream] {
+ /** The factory for streams.
+ * @note Methods such as map/flatMap will not invoke the Builder factory,
+ * but will return a new stream directly, to preserve laziness.
+ * The new stream is then cast to the factory's result type.
+ * This means that every BuilderFactory that takes a
+ * Stream as its From type parameter must yield a stream as its result parameter.
+ * If that assumption is broken, cast errors might result.
+ */
class StreamBuilderFactory[A] extends VirtualBuilderFactory[A]
implicit def builderFactory[A]: BuilderFactory[A, Stream[A], Coll] = new StreamBuilderFactory[A]