diff options
author | Paul Phillips <paulp@improving.org> | 2010-10-11 23:17:47 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-10-11 23:17:47 +0000 |
commit | e5c22d9e0a11f0c1a0d29520f7420d709fb174ec (patch) | |
tree | 819aed10c296f998cc082acb24b4835cd2eca224 /src/library/scala/Tuple2.scala | |
parent | 5c83be3b2bb200f53abd5e3c6667e78ce01ebe49 (diff) | |
download | scala-e5c22d9e0a11f0c1a0d29520f7420d709fb174ec.tar.gz scala-e5c22d9e0a11f0c1a0d29520f7420d709fb174ec.tar.bz2 scala-e5c22d9e0a11f0c1a0d29520f7420d709fb174ec.zip |
An overhaul of the collection-oriented methods ...
An overhaul of the collection-oriented methods in Tuple2/Tuple3 (which
still need to be taken all the way to Tuple5.)
* Zip semantics: zip and zipped now properly terminate when any
collection runs out of elements, even if others are infinite. In
addition, short circuiting methods (exists and forall) will terminate if
the condition is met, even in the presence of infinity.
Example:
scala> val ys = Stream from 1
ys: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> (ys, ys).zipped forall ((x, y) => x+y < 100)
res0: Boolean = false
scala> (ys, ys).zipped exists ((x, y) => x+y > 100)
res1: Boolean = true
* There are implicits converting Zipped2/3 to Traversable to expose all
the methods which aren't defined in an arity-specific way in the tuple
classes. I have mixed feelings about putting these in Predef; but if
there is another way to make them visible by default I wasn't able to
find it.
Example putting said implicit to use:
scala> (ys, ys, ys).zipped find { case (x, y, z) => x+y+z > 1000 }
res0: Option[(Int, Int, Int)] = Some((334,334,334))
Already reviewed by moors, so no review.
Diffstat (limited to 'src/library/scala/Tuple2.scala')
-rw-r--r-- | src/library/scala/Tuple2.scala | 89 |
1 files changed, 48 insertions, 41 deletions
diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index 9948206329..460dd0e6aa 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -7,12 +7,12 @@ \* */ -// generated by genprod on Thu Sep 09 09:06:40 PDT 2010 (with extra methods) +// generated by genprod on Thu Sep 16 10:52:35 PDT 2010 (with extra methods) package scala -import scala.collection.{TraversableLike, IterableLike} -import scala.collection.generic.CanBuildFrom +import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } +import scala.collection.generic.{ CanBuildFrom => CBF } @@ -28,17 +28,20 @@ case class Tuple2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, D /** Swap the elements of the tuple */ def swap: Tuple2[T2,T1] = Tuple2(_2, _1) - def zip[Repr1, El1, El2, To](implicit w1: T1 => TraversableLike[El1, Repr1], + def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => Iterable[El2], - cbf1: CanBuildFrom[Repr1, (El1, El2), To]): To = { - val coll1: TraversableLike[El1, Repr1] = _1 + cbf1: CBF[Repr1, (El1, El2), To]): To = { + val coll1: TLike[El1, Repr1] = _1 val coll2: Iterable[El2] = _2 val b1 = cbf1(coll1.repr) val elems2 = coll2.iterator - for(el1 <- coll1) - if(elems2.hasNext) + for (el1 <- coll1) { + if (elems2.hasNext) b1 += ((el1, elems2.next)) + else + return b1.result + } b1.result } @@ -48,79 +51,83 @@ case class Tuple2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, D * @see Zipped * $willNotTerminateInf */ - def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TraversableLike[El1, Repr1], w2: T2 => IterableLike[El2, Repr2]): Zipped[Repr1, El1, Repr2, El2] + def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => ILike[El2, Repr2]): Zipped[Repr1, El1, Repr2, El2] = new Zipped[Repr1, El1, Repr2, El2](_1, _2) - class Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TraversableLike[El1, Repr1], coll2: IterableLike[El2, Repr2]) { // coll2: IterableLike for filter - def map[B, To](f: (El1, El2) => B)(implicit cbf: CanBuildFrom[Repr1, B, To]): To = { + class Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2]) { // coll2: ILike for filter + def map[B, To](f: (El1, El2) => B)(implicit cbf: CBF[Repr1, B, To]): To = { val b = cbf(coll1.repr) b.sizeHint(coll1) val elems2 = coll2.iterator - for(el1 <- coll1) - if(elems2.hasNext) - b += f(el1, elems2.next) + for (el1 <- coll1) { + if (elems2.hasNext) + b += f(el1, elems2.next) + else + return b.result + } b.result } - def flatMap[B, To](f: (El1, El2) => Traversable[B])(implicit cbf: CanBuildFrom[Repr1, B, To]): To = { + def flatMap[B, To](f: (El1, El2) => Traversable[B])(implicit cbf: CBF[Repr1, B, To]): To = { val b = cbf(coll1.repr) val elems2 = coll2.iterator - for(el1 <- coll1) - if(elems2.hasNext) - b ++= f(el1, elems2.next) + for (el1 <- coll1) { + if (elems2.hasNext) + b ++= f(el1, elems2.next) + else + return b.result + } b.result } - def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CanBuildFrom[Repr1, El1, To1], cbf2: CanBuildFrom[Repr2, El2, To2]): (To1, To2) = { + def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { val b1 = cbf1(coll1.repr) val b2 = cbf2(coll2.repr) val elems2 = coll2.iterator - for(el1 <- coll1) { - if(elems2.hasNext) { + for (el1 <- coll1) { + if (elems2.hasNext) { val el2 = elems2.next - if(f(el1, el2)) { + if (f(el1, el2)) { b1 += el1 b2 += el2 } } + else return (b1.result, b2.result) } (b1.result, b2.result) } def exists(f: (El1, El2) => Boolean): Boolean = { - var acc = false val elems2 = coll2.iterator - for(el1 <- coll1) - if(!acc && elems2.hasNext) - acc = f(el1, elems2.next) - - acc + for (el1 <- coll1) { + if (elems2.hasNext) { + if (f(el1, elems2.next)) + return true + } + else return false + } + false } - def forall(f: (El1, El2) => Boolean): Boolean = { - var acc = true - val elems2 = coll2.iterator - - for(el1 <- coll1) - if(acc && elems2.hasNext) - acc = f(el1, elems2.next) - - acc - } + def forall(f: (El1, El2) => Boolean): Boolean = + !exists((x, y) => !f(x, y)) def foreach[U](f: (El1, El2) => U): Unit = { val elems2 = coll2.iterator - for(el1 <- coll1) - if(elems2.hasNext) - f(el1, elems2.next) + for (el1 <- coll1) { + if (elems2.hasNext) + f(el1, elems2.next) + else + return + } } } |