From 66a92814a61c62149a49335f65f4189763b43296 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 29 Nov 2010 23:00:07 +0000 Subject: 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. --- src/build/genprod.scala | 4 +- src/library/scala/Enumeration.scala | 2 +- src/library/scala/Tuple2.scala | 2 +- src/library/scala/Tuple3.scala | 2 +- .../scala/collection/IterableViewLike.scala | 2 +- src/library/scala/collection/Iterator.scala | 48 ++-------------------- src/library/scala/collection/SeqViewLike.scala | 2 +- src/library/scala/collection/Traversable.scala | 2 +- src/library/scala/collection/TraversableLike.scala | 8 ++-- src/library/scala/collection/TraversableOnce.scala | 42 +++++++++++++++++++ .../scala/collection/TraversableProxyLike.scala | 2 +- .../scala/collection/TraversableViewLike.scala | 6 +-- .../scala/collection/generic/FilterMonadic.scala | 2 +- .../generic/GenericTraversableTemplate.scala | 4 +- .../scala/collection/immutable/Stream.scala | 14 +++---- .../collection/immutable/StreamViewLike.scala | 2 +- .../collection/interfaces/TraversableMethods.scala | 2 +- .../collection/parallel/ParIterableLike.scala | 4 +- .../collection/parallel/ParIterableViewLike.scala | 4 +- .../collection/parallel/RemainsIterator.scala | 2 +- .../collection/parallel/mutable/ParArray.scala | 2 +- test/files/pos/iterator-traversable-mix.scala | 8 ++++ 22 files changed, 87 insertions(+), 79 deletions(-) create mode 100644 test/files/pos/iterator-traversable-mix.scala diff --git a/src/build/genprod.scala b/src/build/genprod.scala index cc941051c7..4920100c1c 100644 --- a/src/build/genprod.scala +++ b/src/build/genprod.scala @@ -343,7 +343,7 @@ object TupleTwo extends Tuple(2) b.result } - def flatMap[B, To](f: (El1, El2) => Traversable[B])(implicit cbf: CBF[Repr1, B, To]): To = { + def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { val b = cbf(coll1.repr) val elems2 = coll2.iterator @@ -454,7 +454,7 @@ object TupleThree extends Tuple(3) { b.result } - def flatMap[B, To](f: (El1, El2, El3) => Traversable[B])(implicit cbf: CBF[Repr1, B, To]): To = { + def flatMap[B, To](f: (El1, El2, El3) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { val b = cbf(coll1.repr) val elems2 = coll2.iterator val elems3 = coll3.iterator diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index 871de3714d..36ead577f6 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -309,7 +309,7 @@ abstract class Enumeration(initial: Int, names: String*) { * concatenates the results. */ @deprecated("use values.flatMap instead") - def flatMap[B](f: Value => Iterator[B]): Iterator[B] = this.iterator flatMap f + def flatMap[B](f: Value => TraversableOnce[B]): Iterator[B] = this.iterator flatMap f /** Returns all values of this enumeration that satisfy the predicate p. * The order of values is preserved. diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index 50d584f3b8..10d92170a5 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -58,7 +58,7 @@ case class Tuple2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, D b.result } - def flatMap[B, To](f: (El1, El2) => Traversable[B])(implicit cbf: CBF[Repr1, B, To]): To = { + def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { val b = cbf(coll1.repr) val elems2 = coll2.iterator diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala index abd47a59b9..d720920a25 100644 --- a/src/library/scala/Tuple3.scala +++ b/src/library/scala/Tuple3.scala @@ -60,7 +60,7 @@ case class Tuple3[+T1, +T2, +T3](_1:T1,_2:T2,_3:T3) b.result } - def flatMap[B, To](f: (El1, El2, El3) => Traversable[B])(implicit cbf: CBF[Repr1, B, To]): To = { + def flatMap[B, To](f: (El1, El2, El3) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { val b = cbf(coll1.repr) val elems2 = coll2.iterator val elems3 = coll3.iterator diff --git a/src/library/scala/collection/IterableViewLike.scala b/src/library/scala/collection/IterableViewLike.scala index 9f77c6965b..a7578e9a01 100644 --- a/src/library/scala/collection/IterableViewLike.scala +++ b/src/library/scala/collection/IterableViewLike.scala @@ -109,7 +109,7 @@ extends Iterable[A] with IterableLike[A, This] with TraversableView[A, Coll] wit protected override def newForced[B](xs: => Seq[B]): Transformed[B] = new Forced[B] { val forced = xs } protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that } protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f } - protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } + protected override def newFlatMapped[B](f: A => TraversableOnce[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p } protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until } protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p } diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index b8dd03110d..31ab2a0eb4 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -149,46 +149,6 @@ object Iterator { def next = elem } - /** With the advent of TraversableOnce, it can be useful to have a builder - * for Iterators so they can be treated uniformly along with the collections. - * See scala.util.Random.shuffle for an example. - */ - class IteratorCanBuildFrom[A] extends generic.CanBuildFrom[Iterator[A], A, Iterator[A]] { - def newIterator = new ArrayBuffer[A] mapResult (_.iterator) - - /** Creates a new builder on request of a collection. - * @param from the collection requesting the builder to be created. - * @return the result of invoking the `genericBuilder` method on `from`. - */ - def apply(from: Iterator[A]) = newIterator - - /** Creates a new builder from scratch - * @return the result of invoking the `newBuilder` method of this factory. - */ - def apply() = newIterator - } - - implicit def iteratorCanBuildFrom[T]: IteratorCanBuildFrom[T] = new IteratorCanBuildFrom[T] - - /** A wrapper class for the `flatten` method that is added to - * class `Iterator` with implicit conversion - * @see iteratorIteratorWrapper. - */ - class IteratorIteratorOps[A](its: Iterator[Iterator[A]]) { - /** If `its` is an iterator of iterators, `its.flatten` gives the iterator - * that is the concatenation of all iterators in `its`. - */ - def flatten: Iterator[A] = new Iterator[A] { - private var it: Iterator[A] = empty - def hasNext: Boolean = it.hasNext || its.hasNext && { it = its.next(); hasNext } - def next(): A = if (hasNext) it.next() else empty.next() - } - } - - /** An implicit conversion which adds the `flatten` method to class `Iterator` */ - implicit def iteratorIteratorWrapper[A](its: Iterator[Iterator[A]]): IteratorIteratorOps[A] = - new IteratorIteratorOps[A](its) - @deprecated("use `xs.iterator' or `Iterator(xs)' instead") def fromValues[a](xs: a*) = xs.iterator @@ -375,13 +335,13 @@ trait Iterator[+A] extends TraversableOnce[A] { * iterator followed by the values produced by iterator `that`. * @usecase def ++(that: => Iterator[A]): Iterator[A] */ - def ++[B >: A](that: => Iterator[B]): Iterator[B] = new Iterator[B] { + def ++[B >: A](that: => TraversableOnce[B]): Iterator[B] = new Iterator[B] { // optimize a little bit to prevent n log n behavior. private var cur : Iterator[B] = self // since that is by-name, make sure it's only referenced once - // if "val it = that" is inside the block, then hasNext on an empty // iterator will continually reevaluate it. (ticket #3269) - lazy val it = that + lazy val it = that.toIterator // the eq check is to avoid an infinite loop on "x ++ x" def hasNext = cur.hasNext || ((cur eq self) && { it.hasNext && { @@ -399,10 +359,10 @@ trait Iterator[+A] extends TraversableOnce[A] { * @return the iterator resulting from applying the given iterator-valued function * `f` to each value produced by this iterator and concatenating the results. */ - def flatMap[B](f: A => Iterator[B]): Iterator[B] = new Iterator[B] { + def flatMap[B](f: A => TraversableOnce[B]): Iterator[B] = new Iterator[B] { private var cur: Iterator[B] = empty def hasNext: Boolean = - cur.hasNext || self.hasNext && { cur = f(self.next); hasNext } + cur.hasNext || self.hasNext && { cur = f(self.next).toIterator; hasNext } def next(): B = (if (hasNext) cur else empty).next() } diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala index 3231720bb3..88b95dd94f 100644 --- a/src/library/scala/collection/SeqViewLike.scala +++ b/src/library/scala/collection/SeqViewLike.scala @@ -173,7 +173,7 @@ trait SeqViewLike[+A, protected override def newForced[B](xs: => Seq[B]): Transformed[B] = new Forced[B] { val forced = xs } protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that } protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f } - protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } + protected override def newFlatMapped[B](f: A => TraversableOnce[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p } protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until } protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p } diff --git a/src/library/scala/collection/Traversable.scala b/src/library/scala/collection/Traversable.scala index dcea1a8c2f..3304ad0135 100644 --- a/src/library/scala/collection/Traversable.scala +++ b/src/library/scala/collection/Traversable.scala @@ -28,7 +28,7 @@ trait Traversable[+A] extends TraversableLike[A, Traversable[A]] override def hasDefiniteSize override def ++[B >: A, That](xs: TraversableOnce[B])(implicit bf: CanBuildFrom[Traversable[A], B, That]): That override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Traversable[A], B, That]): That - override def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[Traversable[A], B, That]): That + override def flatMap[B, That](f: A => TraversableOnce[B])(implicit bf: CanBuildFrom[Traversable[A], B, That]): That override def filter(p: A => Boolean): Traversable[A] override def remove(p: A => Boolean): Traversable[A] override def partition(p: A => Boolean): (Traversable[A], Traversable[A]) diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala index a307ccbf3f..c4765fb89e 100644 --- a/src/library/scala/collection/TraversableLike.scala +++ b/src/library/scala/collection/TraversableLike.scala @@ -217,12 +217,12 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr] * @return a new collection of type `That` resulting from applying the given collection-valued function * `f` to each element of this $coll and concatenating the results. * - * @usecase def flatMap[B](f: A => Traversable[B]): $Coll[B] + * @usecase def flatMap[B](f: A => TraversableOnce[B]): $Coll[B] * * @return a new $coll resulting from applying the given collection-valued function * `f` to each element of this $coll and concatenating the results. */ - def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = { + def flatMap[B, That](f: A => TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = { val b = bf(repr) for (x <- this) b ++= f(x) b.result @@ -797,12 +797,12 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr] * @return a new collection of type `That` resulting from applying the given collection-valued function * `f` to each element of the outer $coll that satisfies predicate `p` and concatenating the results. * - * @usecase def flatMap[B](f: A => Traversable[B]): $Coll[B] + * @usecase def flatMap[B](f: A => TraversableOnce[B]): $Coll[B] * * @return a new $coll resulting from applying the given collection-valued function * `f` to each element of the outer $coll that satisfies predicate `p` and concatenating the results. */ - def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = { + def flatMap[B, That](f: A => TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = { val b = bf(repr) for (x <- self) if (p(x)) b ++= f(x) diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index 1011108d8e..179051553e 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -591,3 +591,45 @@ trait TraversableOnce[+A] { */ def addString(b: StringBuilder): StringBuilder = addString(b, "") } + +object TraversableOnce { + implicit def traversableOnceCanBuildFrom[T]: TraversableOnceCanBuildFrom[T] = + new TraversableOnceCanBuildFrom[T] + + implicit def wrapTraversableOnce[A](trav: TraversableOnce[A]): TraversableOnceMonadOps[A] = + new TraversableOnceMonadOps(trav) + + implicit def flattenTraversableOnce[A](travs: TraversableOnce[TraversableOnce[A]]): TraversableOnceFlattenOps[A] = + new TraversableOnceFlattenOps[A](travs) + + /** With the advent of TraversableOnce, it can be useful to have a builder which + * operates on Iterators so they can be treated uniformly along with the collections. + * See scala.util.Random.shuffle for an example. + */ + class TraversableOnceCanBuildFrom[A] extends generic.CanBuildFrom[TraversableOnce[A], A, TraversableOnce[A]] { + def newIterator = new ArrayBuffer[A] mapResult (_.iterator) + + /** Creates a new builder on request of a collection. + * @param from the collection requesting the builder to be created. + * @return the result of invoking the `genericBuilder` method on `from`. + */ + def apply(from: TraversableOnce[A]) = newIterator + + /** Creates a new builder from scratch + * @return the result of invoking the `newBuilder` method of this factory. + */ + def apply() = newIterator + } + + class TraversableOnceFlattenOps[A](travs: TraversableOnce[TraversableOnce[A]]) { + def flatten: Iterator[A] = travs.foldLeft(Iterator.empty: Iterator[A])(_ ++ _) + } + + class TraversableOnceMonadOps[+A](trav: TraversableOnce[A]) { + def map[B](f: A => B): TraversableOnce[B] = trav.toIterator map f + def flatMap[B](f: A => TraversableOnce[B]): TraversableOnce[B] = trav.toIterator flatMap f + def filter(p: A => Boolean): TraversableOnce[A] = trav.toIterator filter p + def withFilter(p: A => Boolean) = filter(p) + } +} + diff --git a/src/library/scala/collection/TraversableProxyLike.scala b/src/library/scala/collection/TraversableProxyLike.scala index f2d91ded0c..eb6c06fc64 100644 --- a/src/library/scala/collection/TraversableProxyLike.scala +++ b/src/library/scala/collection/TraversableProxyLike.scala @@ -32,7 +32,7 @@ trait TraversableProxyLike[+A, +Repr <: TraversableLike[A, Repr] with Traversabl override def hasDefiniteSize = self.hasDefiniteSize override def ++[B >: A, That](xs: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = self.++(xs)(bf) override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = self.map(f)(bf) - override def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = self.flatMap(f)(bf) + override def flatMap[B, That](f: A => TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = self.flatMap(f)(bf) override def filter(p: A => Boolean): Repr = self.filter(p) override def filterNot(p: A => Boolean): Repr = self.filterNot(p) override def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Repr, B, That]): That = self.collect(pf)(bf) diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala index 7c078ae5d6..a5c2b09141 100644 --- a/src/library/scala/collection/TraversableViewLike.scala +++ b/src/library/scala/collection/TraversableViewLike.scala @@ -108,7 +108,7 @@ self => } trait FlatMapped[B] extends Transformed[B] { - protected[this] val mapping: A => Traversable[B] + protected[this] val mapping: A => TraversableOnce[B] override def foreach[U](f: B => U) { for (x <- self) for (y <- mapping(x)) @@ -164,7 +164,7 @@ self => protected def newForced[B](xs: => Seq[B]): Transformed[B] = new Forced[B] { val forced = xs } protected def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that } protected def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f } - protected def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } + protected def newFlatMapped[B](f: A => TraversableOnce[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } protected def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p } protected def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until } protected def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p } @@ -186,7 +186,7 @@ self => override def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[This, B, That]): That = filter(pf.isDefinedAt).map(pf)(bf) - override def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[This, B, That]): That = { + override def flatMap[B, That](f: A => TraversableOnce[B])(implicit bf: CanBuildFrom[This, B, That]): That = { newFlatMapped(f).asInstanceOf[That] // was: val b = bf(repr) // if (b.isInstanceOf[NoBuilder[_]]) newFlatMapped(f).asInstanceOf[That] diff --git a/src/library/scala/collection/generic/FilterMonadic.scala b/src/library/scala/collection/generic/FilterMonadic.scala index 45bba19e96..7e468a9c96 100755 --- a/src/library/scala/collection/generic/FilterMonadic.scala +++ b/src/library/scala/collection/generic/FilterMonadic.scala @@ -5,7 +5,7 @@ package scala.collection.generic */ trait FilterMonadic[+A, +Repr] { def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That - def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[Repr, B, That]): That + def flatMap[B, That](f: A => TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That def foreach[U](f: A => U): Unit def withFilter(p: A => Boolean): FilterMonadic[A, Repr] } diff --git a/src/library/scala/collection/generic/GenericTraversableTemplate.scala b/src/library/scala/collection/generic/GenericTraversableTemplate.scala index 2d9e732b72..5e72bdeaa7 100644 --- a/src/library/scala/collection/generic/GenericTraversableTemplate.scala +++ b/src/library/scala/collection/generic/GenericTraversableTemplate.scala @@ -96,7 +96,7 @@ trait GenericTraversableTemplate[+A, +CC[X] <: Traversable[X]] extends HasNewBui * @return a new $coll resulting from concatenating all element ${coll}s. * @usecase def flatten[B]: $Coll[B] */ - def flatten[B](implicit asTraversable: A => /*<: /*<: /*<: /*<: * @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 f(a0) ::: ... ::: f(an) if * this stream is [a0, ..., an]. */ - 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 => /*<: /*<: collection.Seq[B]): Transformed[B] = new Forced[B] { val forced = xs } protected override def newAppended[B >: A](that: collection.Traversable[B]): Transformed[B] = new Appended[B] { val rest = that } protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f } - protected override def newFlatMapped[B](f: A => collection.Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } + protected override def newFlatMapped[B](f: A => collection.TraversableOnce[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p } protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until } protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p } diff --git a/src/library/scala/collection/interfaces/TraversableMethods.scala b/src/library/scala/collection/interfaces/TraversableMethods.scala index 9c1ff319ab..4156fecea2 100644 --- a/src/library/scala/collection/interfaces/TraversableMethods.scala +++ b/src/library/scala/collection/interfaces/TraversableMethods.scala @@ -20,7 +20,7 @@ trait TraversableMethods[+A, +This <: TraversableLike[A, This]] extends Traversa self: Traversable[A] => // maps/iteration - def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[This, B, That]): That + def flatMap[B, That](f: A => TraversableOnce[B])(implicit bf: CanBuildFrom[This, B, That]): That def map[B, That](f: A => B)(implicit bf: CanBuildFrom[This, B, That]): That def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[This, B, That]): That def scanLeft[B, That](z: B)(op: (B, A) => B)(implicit bf: CanBuildFrom[This, B, That]): That diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala index 9cbe6fc655..53a219ca28 100644 --- a/src/library/scala/collection/parallel/ParIterableLike.scala +++ b/src/library/scala/collection/parallel/ParIterableLike.scala @@ -415,7 +415,7 @@ self => executeAndWaitResult(new Collect[S, That](pf, pbf, parallelIterator) mapResult { _.result }) } otherwise super.collect(pf)(bf) - override def flatMap[S, That](f: T => Traversable[S])(implicit bf: CanBuildFrom[Repr, S, That]): That = bf ifParallel { pbf => + override def flatMap[S, That](f: T => TraversableOnce[S])(implicit bf: CanBuildFrom[Repr, S, That]): That = bf ifParallel { pbf => executeAndWaitResult(new FlatMap[S, That](f, pbf, parallelIterator) mapResult { _.result }) } otherwise super.flatMap(f)(bf) @@ -869,7 +869,7 @@ self => override def merge(that: Collect[S, That]) = result = result combine that.result } - protected[this] class FlatMap[S, That](f: T => Traversable[S], pbf: CanCombineFrom[Repr, S, That], protected[this] val pit: ParIterableIterator[T]) + protected[this] class FlatMap[S, That](f: T => TraversableOnce[S], pbf: CanCombineFrom[Repr, S, That], protected[this] val pit: ParIterableIterator[T]) extends Transformer[Combiner[S, That], FlatMap[S, That]] { var result: Combiner[S, That] = null def leaf(prev: Option[Combiner[S, That]]) = result = pit.flatmap2combiner(f, pbf(self.repr)) diff --git a/src/library/scala/collection/parallel/ParIterableViewLike.scala b/src/library/scala/collection/parallel/ParIterableViewLike.scala index 4192b0be5c..570abdcea6 100644 --- a/src/library/scala/collection/parallel/ParIterableViewLike.scala +++ b/src/library/scala/collection/parallel/ParIterableViewLike.scala @@ -113,7 +113,7 @@ self => val (pref, suff) = thisParSeq.span(p) (newForced(pref).asInstanceOf[This], newForced(suff).asInstanceOf[This]) } - override def flatMap[S, That](f: T => Traversable[S])(implicit bf: CanBuildFrom[This, S, That]): That = newForced(thisParSeq.flatMap(f)).asInstanceOf[That] + override def flatMap[S, That](f: T => TraversableOnce[S])(implicit bf: CanBuildFrom[This, S, That]): That = newForced(thisParSeq.flatMap(f)).asInstanceOf[That] override def zip[U >: T, S, That](that: Iterable[S])(implicit bf: CanBuildFrom[This, (U, S), That]): That = newZippedTryParSeq(that).asInstanceOf[That] override def zipWithIndex[U >: T, That](implicit bf: CanBuildFrom[This, (U, Int), That]): That = @@ -137,7 +137,7 @@ self => protected override def newAppended[U >: T](that: Traversable[U]): Transformed[U] = new Appended[U] { val rest = that } protected override def newDroppedWhile(p: T => Boolean) = unsupported protected override def newTakenWhile(p: T => Boolean) = unsupported - protected override def newFlatMapped[S](f: T => Traversable[S]) = unsupported + protected override def newFlatMapped[S](f: T => TraversableOnce[S]) = unsupported protected override def newFiltered(p: T => Boolean) = unsupported protected override def newZipped[S](that: Iterable[S]): Transformed[(T, S)] = new Zipped[S] { val other = that } protected override def newZippedAll[U >: T, S](that: Iterable[S], _thisElem: U, _thatElem: S): Transformed[(U, S)] = new ZippedAll[U, S] { diff --git a/src/library/scala/collection/parallel/RemainsIterator.scala b/src/library/scala/collection/parallel/RemainsIterator.scala index cc0f2c0669..a33702a527 100644 --- a/src/library/scala/collection/parallel/RemainsIterator.scala +++ b/src/library/scala/collection/parallel/RemainsIterator.scala @@ -105,7 +105,7 @@ trait AugmentedIterableIterator[+T] extends RemainsIterator[T] { cb } - def flatmap2combiner[S, That](f: T => Traversable[S], cb: Combiner[S, That]): Combiner[S, That] = { + def flatmap2combiner[S, That](f: T => TraversableOnce[S], cb: Combiner[S, That]): Combiner[S, That] = { //val cb = pbf(repr) while (hasNext) { val traversable = f(next) diff --git a/src/library/scala/collection/parallel/mutable/ParArray.scala b/src/library/scala/collection/parallel/mutable/ParArray.scala index f02775f332..a1164b7b80 100644 --- a/src/library/scala/collection/parallel/mutable/ParArray.scala +++ b/src/library/scala/collection/parallel/mutable/ParArray.scala @@ -393,7 +393,7 @@ self => } } - override def flatmap2combiner[S, That](f: T => Traversable[S], cb: Combiner[S, That]): Combiner[S, That] = { + override def flatmap2combiner[S, That](f: T => TraversableOnce[S], cb: Combiner[S, That]): Combiner[S, That] = { //val cb = pbf(self.repr) while (i < until) { val traversable = f(arr(i).asInstanceOf[T]) diff --git a/test/files/pos/iterator-traversable-mix.scala b/test/files/pos/iterator-traversable-mix.scala new file mode 100644 index 0000000000..2d6bf44c70 --- /dev/null +++ b/test/files/pos/iterator-traversable-mix.scala @@ -0,0 +1,8 @@ +object Test { + for { + x1 <- List(1, 2) + x2 <- Iterator(3, 4) + x3 <- Seq(5, 6).iterator + x4 <- Stream(7, 8) + } yield x1+x2+x3+x4 +} -- cgit v1.2.3