diff options
author | Martin Odersky <odersky@gmail.com> | 2009-07-14 15:35:07 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2009-07-14 15:35:07 +0000 |
commit | 0be42af7a28a92739712636289009f3996370388 (patch) | |
tree | 16a35a681c97dba957cb6036c95874897fd82109 /src | |
parent | ac779096c1c2c6e3e1d563855bfc20fb76b04746 (diff) | |
download | scala-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
Diffstat (limited to 'src')
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] |