1212
1313package scala
1414
15- import annotation .unchecked .uncheckedVariance
16- import scala .collection .generic .GenericTraversableTemplate
17- import scala .collection .mutable .Builder
15+ import scala .collection .{TraversableLike , Traversable , IterableLike }
16+ import scala .collection .generic .CanBuildFrom
1817
1918
2019/** Tuple2 is the canonical representation of a @see Product2
@@ -30,55 +29,80 @@ case class Tuple2[+T1, +T2](_1:T1, _2:T2) extends Product2[T1, T2] {
3029 /** Swap the elements of the tuple */
3130 def swap : Tuple2 [T2 ,T1 ] = Tuple2 (_2, _1)
3231
33- /*
34- type Traverserable[CC[X] <: Traversable[X], X] = GenericTraversableTemplate[X, CC] with Iterable[X]
32+ def zipped [ Repr1 , El1 , Repr2 , El2 ]( implicit w1 : T1 <:< TraversableLike [ El1 , Repr1 ], w2 : T2 <:< IterableLike [ El2 , Repr2 ]) : Zipped [ Repr1 , El1 , Repr2 , El2 ]
33+ = new Zipped [ Repr1 , El1 , Repr2 , El2 ](_1, _2)
3534
36- // TODO: benchmark factored version vs inlining forall2 everywhere (specialisation?)
37- // factor further? (use fold2)
38- // must use <:< instead of =>, otherwise bogus any2stringadd conversion is also eligible (in case of type errors)
35+ class Zipped [+ Repr1 , + El1 , + Repr2 , + El2 ](coll1 : TraversableLike [El1 , Repr1 ], coll2 : IterableLike [El2 , Repr2 ]) { // coll2: IterableLike for filter
36+ def it : (Repr1 , Repr2 ) = (coll1.repr, coll2.repr) // TODO: do we want this? what should its name be?
3937
38+ def map [B , To ](f : (El1 , El2 ) => B )(implicit cbf : CanBuildFrom [Repr1 , B , To ]): To = {
39+ val b = cbf(coll1.repr)
40+ val elems2 = coll2.iterator
4041
41- def forall2[CC[X] <: Traverserable[CC, X], A1, A2](f: (A1, A2) => Boolean)(implicit fst: T1 <:< CC[A1], snd: T2 <:< Traverserable[Iterable, A2]/* CC[A2] does not work*/ ): Boolean = {
42- val it1 = _1.iterator
43- val it2 = _2.iterator
44- var res = true
45- while (res && it1.hasNext && it2.hasNext)
46- res = f(it1.next, it2.next)
47- res
48- }
42+ for (el1 <- coll1)
43+ if (elems2.hasNext)
44+ b += f(el1, elems2.next)
4945
50- def exists2[CC[X] <: Traverserable[CC, X], A1, A2](f: (A1, A2) => Boolean)(implicit fst: T1 <:< CC[A1], snd: T2 <:< Traverserable[Iterable, A2]/* CC[A2] does not work*/ ): Boolean = {
51- val it1 = _1.iterator
52- val it2 = _2.iterator
53- var res = false
54- while (!res && it1.hasNext && it2.hasNext)
55- res = f(it1.next, it2.next)
56- res
57- }
46+ b.result
47+ }
5848
59- def foreach2[CC[X] <: Traverserable[CC, X], A1, A2, U](f: (A1, A2) => U)(implicit fst: T1 <:< CC[A1], snd: T2 <:< Traverserable[Iterable, A2]/* CC[A2] does not work*/ ): Unit
60- = forall2[CC, A1, A2]{(x, y) => f(x, y); true} // XXX: remove type args and fix crash in type infer
49+ def flatMap [B , To ](f : (El1 , El2 ) => Traversable [B ])(implicit cbf : CanBuildFrom [Repr1 , B , To ]): To = {
50+ val b = cbf(coll1.repr)
51+ val elems2 = coll2.iterator
6152
62- def build2[CC[X] <: Traverserable[CC, X], A1, A2, B](f: Builder[B, CC[B]] => (A1, A2) => Unit)(implicit fst: T1 <:< CC[A1], snd: T2 <:< Traverserable[Iterable, A2]/* CC[A2] does not work*/ ): CC[B] = {
63- val b = _1.genericBuilder[B]
64- foreach2[CC, A1, A2, Unit](f(b)) // XXX: remove type args and fix crash in type infer
65- b.result
66- }
53+ for (el1 <- coll1)
54+ if (elems2.hasNext)
55+ b ++= f(el1, elems2.next)
6756
68- def zip2[CC[X] <: Traverserable[CC, X], A1, A2](implicit fst: T1 <:< CC[A1], snd: T2 <:< Traverserable[Iterable, A2]/* CC[A2] does not work*/ ): CC[(A1, A2)]
69- = build2[CC, A1, A2, (A1, A2)]{b => (x, y) => // XXX: remove type args and fix crash in type infer
70- b += Tuple2(x, y)
71- }
57+ b.result
58+ }
7259
73- def map2[CC[X] <: Traverserable[CC, X], A1, A2, B] (f: (A1, A2 ) => B )(implicit fst: T1 <:< CC[A1 ], snd: T2 <:< Traverserable[Iterable, A2] /* CC[A2] does not work */ ): CC[B]
74- = build2[CC, A1, A2, B]{b => (x, y) => // XXX: remove type args and fix crash in type infer
75- b += f(x, y )
76- }
60+ def filter [ To1 , To2 ] (f : (El1 , El2 ) => Boolean )(implicit cbf1 : CanBuildFrom [ Repr1 , El1 , To1 ], cbf2 : CanBuildFrom [ Repr2 , El2 , To2 ]) : ( To1 , To2 ) = {
61+ val b1 = cbf1(coll1.repr)
62+ val b2 = cbf2(coll2.repr )
63+ val elems2 = coll2.iterator
7764
78- def flatMap2[CC[X] <: Traverserable[CC, X], A1, A2, B](f: (A1, A2) => CC[B])(implicit fst: T1 <:< CC[A1], snd: T2 <:< Traverserable[Iterable, A2]/* CC[A2] does not work*/ ): CC[B]
79- = build2[CC, A1, A2, B]{b => (x, y) => // XXX: remove type args and fix crash in type infer
80- b ++= f(x, y)
65+ for (el1 <- coll1) {
66+ if (elems2.hasNext) {
67+ val el2 = elems2.next
68+ if (f(el1, el2)) {
69+ b1 += el1
70+ b2 += el2
71+ }
72+ }
8173 }
82- */
8374
75+ (b1.result, b2.result)
76+ }
77+
78+ def exists (f : (El1 , El2 ) => Boolean ): Boolean = {
79+ var acc = false
80+ val elems2 = coll2.iterator
81+
82+ for (el1 <- coll1)
83+ if (! acc && elems2.hasNext)
84+ acc = f(el1, elems2.next)
85+
86+ acc
87+ }
88+
89+ def forall (f : (El1 , El2 ) => Boolean ): Boolean = {
90+ var acc = true
91+ val elems2 = coll2.iterator
92+
93+ for (el1 <- coll1)
94+ if (acc && elems2.hasNext)
95+ acc = f(el1, elems2.next)
96+
97+ acc
98+ }
99+
100+ def foreach [U ](f : (El1 , El2 ) => U ): Unit = {
101+ val elems2 = coll2.iterator
102+
103+ for (el1 <- coll1)
104+ if (elems2.hasNext)
105+ f(el1, elems2.next)
106+ }
107+ }
84108}
0 commit comments