diff options
author | Paul Phillips <paulp@improving.org> | 2010-11-29 23:00:07 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-11-29 23:00:07 +0000 |
commit | 66a92814a61c62149a49335f65f4189763b43296 (patch) | |
tree | 981508efdd7a29daa12f3e121d9608e441f26ece /src/library/scala/collection/immutable/Stream.scala | |
parent | 4ec7f11a799444c3758e94b3fdf9fa5c26330577 (diff) | |
download | scala-66a92814a61c62149a49335f65f4189763b43296.tar.gz scala-66a92814a61c62149a49335f65f4189763b43296.tar.bz2 scala-66a92814a61c62149a49335f65f4189763b43296.zip |
The initial implementation of TraversableOnce c...
The initial implementation of TraversableOnce could not supply concrete
methods or even signatures for map and flatMap because they have
different signatures in Iterator and TraversableLike. But we can take
another approach which works out as nicely:
1) Create implicits which install those methods and flatten on
TraversableOnce instances. 2) Generalize the signatures of flatten
and flatMap to work with A => TraversableOnce[B] instead of A =>
Traversable[B].
And voila, you can mix and match Iterators and Traversables in a for
comprehension, map, flatMap, and flatten, without the tedious process
of sprinkling .iterator or .toList around to appease the compiler. No
review.
Diffstat (limited to 'src/library/scala/collection/immutable/Stream.scala')
-rw-r--r-- | src/library/scala/collection/immutable/Stream.scala | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index f6acda3b48..0b1453369c 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -77,7 +77,7 @@ self => * @param rest The stream that gets appended to this stream * @return The stream containing elements of this stream and the traversable object. */ - def append[B >: A](rest: => Traversable[B]): Stream[B] = + def append[B >: A](rest: => TraversableOnce[B]): Stream[B] = if (isEmpty) rest.toStream else new Stream.Cons(head, tail append rest) /** Forces evaluation of the whole stream and returns it. */ @@ -187,7 +187,7 @@ self => * @return <code>f(a<sub>0</sub>) ::: ... ::: f(a<sub>n</sub>)</code> if * this stream is <code>[a<sub>0</sub>, ..., a<sub>n</sub>]</code>. */ - override final def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[Stream[A], B, That]): That = + override final def flatMap[B, That](f: A => TraversableOnce[B])(implicit bf: CanBuildFrom[Stream[A], B, That]): That = // we assume there is no other builder factory on streams and therefore know that That = Stream[B] // optimisations are not for speed, but for functionality // see tickets #153, #498, #2147, and corresponding tests in run/ (as well as run/stream_flatmap_odds.scala) @@ -243,7 +243,7 @@ self => } } - override def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[Stream[A], B, That]): That = { + override def flatMap[B, That](f: A => TraversableOnce[B])(implicit bf: CanBuildFrom[Stream[A], B, That]): That = { def tailFlatMap = asStream[B](tail withFilter p flatMap f) ifTargetThis[B, That](bf) { if (isEmpty) Stream.Empty @@ -498,17 +498,15 @@ self => result } - override def flatten[B](implicit asTraversable: A => /*<:<!!!*/ Traversable[B]): Stream[B] = { + override def flatten[B](implicit asTraversable: A => /*<:<!!!*/ TraversableOnce[B]): Stream[B] = { def flatten1(t: Traversable[B]): Stream[B] = if (!t.isEmpty) new Stream.Cons(t.head, flatten1(t.tail)) else tail.flatten - if (isEmpty) - Stream.empty - else - flatten1(asTraversable(head)) + if (isEmpty) Stream.empty + else flatten1(asTraversable(head).toTraversable) } override def view = new StreamView[A, Stream[A]] { |