summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2009-10-27 10:23:01 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2009-10-27 10:23:01 +0000
commit38c3ca67563a68e8f30fd84282b1b9c4cebadeaa (patch)
tree5c6dbdef9f540e986110fb739227bfa0a78acce9 /src
parent42a42ac0c346d48594958ac80d5eb814b8aa0c39 (diff)
downloadscala-38c3ca67563a68e8f30fd84282b1b9c4cebadeaa.tar.gz
scala-38c3ca67563a68e8f30fd84282b1b9c4cebadeaa.tar.bz2
scala-38c3ca67563a68e8f30fd84282b1b9c4cebadeaa.zip
fixed bug in Stream::flatMap (still optimised a...
fixed bug in Stream::flatMap (still optimised as it was needed for correctness --> added regression tests for corresponding tickets)
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/collection/immutable/Stream.scala28
1 files changed, 17 insertions, 11 deletions
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index 9855ce8a41..8694dfd615 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -144,18 +144,24 @@ 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 => Traversable[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]
- // optimization: drop A's for which f yields no B
- var rest = this
- var seg: Traversable[B] = null
- do {
- if (rest.isEmpty) return Stream.Empty.asInstanceOf[That]
- seg = f(rest.head)
- rest = rest.tail
- } while (seg.isEmpty)
- (seg.toStream append (rest flatMap f).asInstanceOf[Stream[B]]).asInstanceOf[That]
- }
+ // 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)
+ (if (isEmpty) Stream.Empty
+ else {
+ // establish !prefix.isEmpty || nonEmptyPrefix.isEmpty
+ var nonEmptyPrefix = this
+ var prefix = f(nonEmptyPrefix.head).toStream
+ while (!nonEmptyPrefix.isEmpty && prefix.isEmpty) {
+ nonEmptyPrefix = nonEmptyPrefix.tail
+ if(!nonEmptyPrefix.isEmpty)
+ prefix = f(nonEmptyPrefix.head).toStream
+ }
+
+ if(nonEmptyPrefix.isEmpty) Stream.empty
+ else prefix append (nonEmptyPrefix.tail flatMap f).asInstanceOf[Stream[B]]
+ }).asInstanceOf[That]
/** Returns all the elements of this stream that satisfy the
* predicate <code>p</code>. The order of the elements is preserved.