Skip to content

Commit 7163c7b

Browse files
committed
Add SeqView. Make sure getting a View’s View is a no-op.
1 parent 4292c0f commit 7163c7b

File tree

6 files changed

+44
-44
lines changed

6 files changed

+44
-44
lines changed

src/main/scala/strawman/collection/MultiDict.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]
101101
* @tparam W new type of values
102102
*/
103103
def map[L, W](f: ((K, V)) => (L, W)): CC[L, W] =
104-
multiMapFromIterable(View.Map(toIterable, f))
104+
multiMapFromIterable(new View.Map(toIterable, f))
105105

106106
/**
107107
* @return a multidict that contains all the entries of `this` multidict,
@@ -112,7 +112,7 @@ trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]
112112
* @tparam W new type of values
113113
*/
114114
def flatMap[L, W](f: ((K, V)) => IterableOnce[(L, W)]): CC[L, W] =
115-
multiMapFromIterable(View.FlatMap(toIterable, f))
115+
multiMapFromIterable(new View.FlatMap(toIterable, f))
116116

117117
/**
118118
* @return a multidict that contains all the entries of `this` multidict
@@ -125,19 +125,19 @@ trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]
125125
*/
126126
def collect[L, W](pf: PartialFunction[(K, V), (L, W)]): CC[L, W] =
127127
flatMap(kv =>
128-
if (pf.isDefinedAt(kv)) View.Single(pf(kv))
128+
if (pf.isDefinedAt(kv)) new View.Single(pf(kv))
129129
else View.Empty
130130
)
131131

132132
/** Concatenate the entries given in `that` iterable to `this` multidict */
133133
def concat(that: Iterable[(K, V)]): C =
134-
fromSpecificIterable(View.Concat(toIterable, that))
134+
fromSpecificIterable(new View.Concat(toIterable, that))
135135

136136
override def withFilter(p: ((K, V)) => Boolean): MultiMapWithFilter = new MultiMapWithFilter(p)
137137

138138
class MultiMapWithFilter(p: ((K, V)) => Boolean) extends WithFilter(p) {
139-
def map[L, W](f: ((K, V)) => (L, W)): CC[L, W] = multiMapFromIterable(View.Map(filtered, f))
140-
def flatMap[L, W](f: ((K, V)) => IterableOnce[(L, W)]): CC[L, W] = multiMapFromIterable(View.FlatMap(filtered, f))
139+
def map[L, W](f: ((K, V)) => (L, W)): CC[L, W] = multiMapFromIterable(new View.Map(filtered, f))
140+
def flatMap[L, W](f: ((K, V)) => IterableOnce[(L, W)]): CC[L, W] = multiMapFromIterable(new View.FlatMap(filtered, f))
141141
override def withFilter(q: ((K, V)) => Boolean): MultiMapWithFilter = new MultiMapWithFilter(kv => p(kv) && q(kv))
142142
}
143143

@@ -157,7 +157,7 @@ trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]
157157
* @tparam W the type of values of the returned multidict
158158
*/
159159
def mapSets[L, W](f: ((K, Set[V])) => (L, Set[W])): CC[L, W] =
160-
fromSets(View.Map(sets, f))
160+
fromSets(new View.Map(sets, f))
161161

162162
/**
163163
* @return a multidict that contains all the entries of `this` multidict,
@@ -170,7 +170,7 @@ trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]
170170
*/
171171
def collectSets[L, W](pf: PartialFunction[(K, Set[V]), (L, Set[W])]): CC[L, W] =
172172
flatMapSets(kvs =>
173-
if (pf.isDefinedAt(kvs)) View.Single(pf(kvs))
173+
if (pf.isDefinedAt(kvs)) new View.Single(pf(kvs))
174174
else View.Empty
175175
)
176176

@@ -183,7 +183,7 @@ trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]
183183
* @tparam W the type of values of the returned multidict
184184
*/
185185
def flatMapSets[L, W](f: ((K, Set[V])) => IterableOnce[(L, Set[W])]): CC[L, W] =
186-
fromSets(View.FlatMap(sets, f))
186+
fromSets(new View.FlatMap(sets, f))
187187

188188
/**
189189
* @return a new multidict concatenating the values of this multidict
@@ -192,14 +192,14 @@ trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]
192192
* @param that the collection of values to add to this multidict
193193
*/
194194
def concatSets(that: Iterable[(K, Set[V])]): C =
195-
fromSpecificSets(View.Concat(sets, that))
195+
fromSpecificSets(new View.Concat(sets, that))
196196

197197
/**
198198
* @return a multidict that contains all the entries of this multidict
199199
* that satisfy the predicate `p`
200200
*/
201201
def filterSets(p: ((K, Set[V])) => Boolean): C =
202-
fromSpecificSets(View.Filter(sets, p, isFlipped = false))
202+
fromSpecificSets(new View.Filter(sets, p, isFlipped = false))
203203

204204
}
205205

src/main/scala/strawman/collection/MultiSet.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,19 @@ trait MultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
3535
extends IterableOps[A, CC, C] {
3636

3737
protected[this] def fromSpecificOccurrences(it: Iterable[(A, Int)]): C =
38-
fromSpecificIterable(it.view.flatMap { case (e, n) => View.Fill(n)(e) })
38+
fromSpecificIterable(it.view.flatMap { case (e, n) => new View.Fill(n)(e) })
3939

4040
protected[this] def fromOccurrences[E](it: Iterable[(E, Int)]): CC[E] =
4141
// Note new MultiSet(it.to(Map)) would be more efficient but would also loose duplicates
42-
fromIterable(it.view.flatMap { case (e, n) => View.Fill(n)(e) })
42+
fromIterable(it.view.flatMap { case (e, n) => new View.Fill(n)(e) })
4343

4444
/**
4545
* @return All the elements contained in this multiset and their number of occurrences
4646
*/
4747
def occurrences: Map[A, Int]
4848

4949
def iterator(): Iterator[A] =
50-
occurrences.iterator().flatMap { case (elem, n) => View.Fill(n)(elem) }
50+
occurrences.iterator().flatMap { case (elem, n) => new View.Fill(n)(elem) }
5151

5252
/**
5353
* @return The number of occurrences of `elem` in this multiset
@@ -68,7 +68,7 @@ trait MultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
6868
* @param that the collection of elements to add to this multiset
6969
*/
7070
def concat(that: Iterable[A]): C =
71-
fromSpecificIterable(View.Concat(toIterable, that))
71+
fromSpecificIterable(new View.Concat(toIterable, that))
7272

7373
/**
7474
* @return a new multiset summing the occurrences of this multiset
@@ -77,7 +77,7 @@ trait MultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
7777
* @param that the collection of occurrences to add to this multiset
7878
*/
7979
def concatOccurrences(that: Iterable[(A, Int)]): C =
80-
fromSpecificOccurrences(View.Concat(occurrences, that))
80+
fromSpecificOccurrences(new View.Concat(occurrences, that))
8181

8282
/**
8383
* @return a new multiset resulting from applying the given function `f`
@@ -87,11 +87,11 @@ trait MultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
8787
* @tparam B the element type of the returned collection
8888
*/
8989
def mapOccurrences[B](f: ((A, Int)) => (B, Int)): CC[B] =
90-
fromOccurrences(View.Map(occurrences, f))
90+
fromOccurrences(new View.Map(occurrences, f))
9191

9292
def collectOccurrences[B](pf: PartialFunction[(A, Int), (B, Int)]): CC[B] =
9393
flatMapOccurrences(kvs =>
94-
if (pf.isDefinedAt(kvs)) View.Single(pf(kvs))
94+
if (pf.isDefinedAt(kvs)) new View.Single(pf(kvs))
9595
else View.Empty
9696
)
9797

@@ -103,14 +103,14 @@ trait MultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
103103
* @tparam B the element type of the returned collection
104104
*/
105105
def flatMapOccurrences[B](f: ((A, Int)) => IterableOnce[(B, Int)]): CC[B] =
106-
fromOccurrences(View.FlatMap(occurrences, f))
106+
fromOccurrences(new View.FlatMap(occurrences, f))
107107

108108
/**
109109
* @return a new multiset containing only the occurrences of elements
110110
* of this multiset that satisfy the given predicate `p`
111111
*/
112112
def filterOccurrences(p: ((A, Int)) => Boolean): C =
113-
fromSpecificOccurrences(View.Filter(occurrences, p, isFlipped = false))
113+
fromSpecificOccurrences(new View.Filter(occurrences, p, isFlipped = false))
114114

115115
// TODO Add more multiset operations like union and intersection
116116

src/main/scala/strawman/collection/SortedMultiDict.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,
5454
override def withFilter(p: ((K, V)) => Boolean): SortedMultiMapWithFilter = new SortedMultiMapWithFilter(p)
5555

5656
class SortedMultiMapWithFilter(p: ((K, V)) => Boolean) extends MultiMapWithFilter(p) {
57-
def map[L : Ordering, W](f: ((K, V)) => (L, W)): CC[L, W] = sortedFromIterable(View.Map(filtered, f))
58-
def flatMap[L : Ordering, W](f: ((K, V)) => IterableOnce[(L, W)]): CC[L, W] = sortedFromIterable(View.FlatMap(filtered, f))
57+
def map[L : Ordering, W](f: ((K, V)) => (L, W)): CC[L, W] = sortedFromIterable(new View.Map(filtered, f))
58+
def flatMap[L : Ordering, W](f: ((K, V)) => IterableOnce[(L, W)]): CC[L, W] = sortedFromIterable(new View.FlatMap(filtered, f))
5959
override def withFilter(q: ((K, V)) => Boolean): SortedMultiMapWithFilter = new SortedMultiMapWithFilter(kv => p(kv) && q(kv))
6060
}
6161

@@ -67,7 +67,7 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,
6767
* @tparam L new type of keys
6868
* @tparam W new type of values
6969
*/
70-
def map[L : Ordering, W](f: ((K, V)) => (L, W)): CC[L, W] = sortedFromIterable(View.Map(toIterable, f))
70+
def map[L : Ordering, W](f: ((K, V)) => (L, W)): CC[L, W] = sortedFromIterable(new View.Map(toIterable, f))
7171

7272
/**
7373
* Builds a new sorted multidict by applying a function to all groups of elements
@@ -78,7 +78,7 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,
7878
* `f` to each pair of element and its number of occurrences of this
7979
* sorted multiset and collecting the results.
8080
*/
81-
def mapSets[L : Ordering, W](f: ((K, Set[V])) => (L, Set[W])): CC[L, W] = sortedFromSets(View.Map(sets, f))
81+
def mapSets[L : Ordering, W](f: ((K, Set[V])) => (L, Set[W])): CC[L, W] = sortedFromSets(new View.Map(sets, f))
8282

8383
/**
8484
* @return a sorted multidict that contains all the entries of `this` sorted multidict,
@@ -88,7 +88,7 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,
8888
* @tparam L new type of keys
8989
* @tparam W new type of values
9090
*/
91-
def flatMap[L : Ordering, W](f: ((K, V)) => IterableOnce[(L, W)]): CC[L, W] = sortedFromIterable(View.FlatMap(toIterable, f))
91+
def flatMap[L : Ordering, W](f: ((K, V)) => IterableOnce[(L, W)]): CC[L, W] = sortedFromIterable(new View.FlatMap(toIterable, f))
9292

9393
/**
9494
* @return a new sorted multidict resulting from applying the given function `f`
@@ -98,7 +98,7 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,
9898
* @tparam L the new type of keys
9999
* @tparam W the type of values of the returned sorted multidict
100100
*/
101-
def flatMapSets[L : Ordering, W](f: ((K, Set[V])) => IterableOnce[(L, Set[W])]): CC[L, W] = sortedFromSets(View.FlatMap(sets, f))
101+
def flatMapSets[L : Ordering, W](f: ((K, Set[V])) => IterableOnce[(L, Set[W])]): CC[L, W] = sortedFromSets(new View.FlatMap(sets, f))
102102

103103
/**
104104
* @return a sorted multidict that contains all the entries of `this` sorted multidict
@@ -110,7 +110,7 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,
110110
* @tparam W new type of values
111111
*/
112112
def collect[L : Ordering, W](pf: PartialFunction[(K, V), (L, W)]): CC[L, W] = flatMap(kv =>
113-
if (pf.isDefinedAt(kv)) View.Single(pf(kv))
113+
if (pf.isDefinedAt(kv)) new View.Single(pf(kv))
114114
else View.Empty
115115
)
116116

@@ -124,7 +124,7 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,
124124
* @tparam W the new type of values
125125
*/
126126
def collectSets[L : Ordering, W](pf: PartialFunction[(K, Set[V]), (L, Set[W])]): CC[L, W] = flatMapSets(kv =>
127-
if (pf.isDefinedAt(kv)) View.Single(pf(kv))
127+
if (pf.isDefinedAt(kv)) new View.Single(pf(kv))
128128
else View.Empty
129129
)
130130

src/main/scala/strawman/collection/SortedMultiSet.scala

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
3030

3131
protected[this] def sortedFromIterable[B : Ordering](it: Iterable[B]): SortedIterableCC[B]
3232
protected[this] def sortedFromOccurrences[B : Ordering](it: Iterable[(B, Int)]): CC[B] =
33-
sortedFromIterable(it.view.flatMap { case (b, n) => View.Fill(n)(b) })
33+
sortedFromIterable(it.view.flatMap { case (b, n) => new View.Fill(n)(b) })
3434

3535
/** `this` sorted multiset upcasted to an unsorted multiset */
3636
def unsorted: MultiSet[A]
@@ -46,7 +46,7 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
4646
* @param start The lower-bound (inclusive) of the iterator
4747
*/
4848
def iteratorFrom(start: A): Iterator[A] =
49-
occurrences.iteratorFrom(start).flatMap { case (elem, n) => View.Fill(n)(elem) }
49+
occurrences.iteratorFrom(start).flatMap { case (elem, n) => new View.Fill(n)(elem) }
5050

5151
def firstKey: A = occurrences.firstKey
5252
def lastKey: A = occurrences.lastKey
@@ -70,9 +70,9 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
7070
*/
7171
class SortedWithFilter(p: A => Boolean) extends WithFilter(p) {
7272

73-
def map[B : Ordering](f: A => B): CC[B] = sortedIterableFactory.from(View.Map(filtered, f))
73+
def map[B : Ordering](f: A => B): CC[B] = sortedIterableFactory.from(new View.Map(filtered, f))
7474

75-
def flatMap[B : Ordering](f: A => IterableOnce[B]): CC[B] = sortedIterableFactory.from(View.FlatMap(filtered, f))
75+
def flatMap[B : Ordering](f: A => IterableOnce[B]): CC[B] = sortedIterableFactory.from(new View.FlatMap(filtered, f))
7676

7777
override def withFilter(q: A => Boolean): SortedWithFilter = new SortedWithFilter(a => p(a) && q(a))
7878

@@ -85,7 +85,7 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
8585
* @return a new collection resulting from applying the given function
8686
* `f` to each element of this sorted multiset and collecting the results.
8787
*/
88-
def map[B : Ordering](f: A => B): CC[B] = sortedFromIterable(View.Map(toIterable, f))
88+
def map[B : Ordering](f: A => B): CC[B] = sortedFromIterable(new View.Map(toIterable, f))
8989

9090
/**
9191
* Builds a new sorted multiset by applying a function to all pairs of element and its
@@ -98,7 +98,7 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
9898
* sorted multiset and collecting the results.
9999
*/
100100
def mapOccurrences[B : Ordering](f: ((A, Int)) => (B, Int)): CC[B] =
101-
sortedFromOccurrences(View.Map(occurrences, f))
101+
sortedFromOccurrences(new View.Map(occurrences, f))
102102

103103
/**
104104
* Builds a new collection by applying a function to all elements of this sorted
@@ -109,7 +109,7 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
109109
* @return a new collection resulting from applying the given function `f` to
110110
* each element of this sorted multiset and concatenating the results.
111111
*/
112-
def flatMap[B : Ordering](f: A => IterableOnce[B]): CC[B] = sortedFromIterable(View.FlatMap(toIterable, f))
112+
def flatMap[B : Ordering](f: A => IterableOnce[B]): CC[B] = sortedFromIterable(new View.FlatMap(toIterable, f))
113113

114114
/**
115115
* Builds a new collection by applying a function to all pairs of element and
@@ -123,7 +123,7 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
123123
* multiset and concatenating the results.
124124
*/
125125
def flatMapOccurrences[B : Ordering](f: ((A, Int)) => IterableOnce[(B, Int)]): CC[B] =
126-
sortedFromOccurrences(View.FlatMap(occurrences, f))
126+
sortedFromOccurrences(new View.FlatMap(occurrences, f))
127127

128128
/**
129129
* Returns a sorted multiset formed from this sorted multiset and another iterable
@@ -136,7 +136,7 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
136136
* is the minimum of the lengths of `this` and `that`
137137
*/
138138
def zip[B](that: Iterable[B])(implicit ev: Ordering[B]): CC[(A @uncheckedVariance, B)] = // sound bcs of VarianceNote
139-
sortedFromIterable(View.Zip(toIterable, that))
139+
sortedFromIterable(new View.Zip(toIterable, that))
140140

141141
/**
142142
* @return a new collection resulting from applying the given partial
@@ -146,7 +146,7 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
146146
* @tparam B the element type of the returned collection
147147
*/
148148
def collect[B : Ordering](pf: PartialFunction[A, B]): CC[B] = flatMap(a =>
149-
if (pf.isDefinedAt(a)) View.Single(pf(a))
149+
if (pf.isDefinedAt(a)) new View.Single(pf(a))
150150
else View.Empty
151151
)
152152

@@ -158,14 +158,14 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
158158
* @tparam B the element type of the returned collection
159159
*/
160160
def collectOccurrences[B : Ordering](pf: PartialFunction[(A, Int), (B, Int)]): CC[B] = flatMapOccurrences(a =>
161-
if (pf.isDefinedAt(a)) View.Single(pf(a))
161+
if (pf.isDefinedAt(a)) new View.Single(pf(a))
162162
else View.Empty
163163
)
164164

165165
// --- Override return type of methods that returned an unsorted MultiSet
166166

167167
override def zipWithIndex: CC[(A, Int)] =
168-
sortedFromIterable(View.ZipWithIndex(toIterable))
168+
sortedFromIterable(new View.ZipWithIndex(toIterable))
169169

170170
}
171171

src/main/scala/strawman/collection/decorators/SeqDecorator.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class SeqDecorator[A, CC[X] <: SeqOps[X, CC, _]](`this`: CC[A]) {
2424
* }}}
2525
*/
2626
def intersperse[B >: A](sep: B): CC[B] =
27-
`this`.iterableFactory.from(View.Intersperse(`this`.toIterable, sep))
27+
`this`.iterableFactory.from(new View.Intersperse(`this`.toIterable, sep))
2828

2929
/** Adds the element `sep` between each element of the sequence,
3030
* prepending `start` and appending `end`.
@@ -42,6 +42,6 @@ class SeqDecorator[A, CC[X] <: SeqOps[X, CC, _]](`this`: CC[A]) {
4242
* }}}
4343
*/
4444
def intersperse[B >: A, C](start: B, sep: B, end: B): CC[B] =
45-
`this`.iterableFactory.from(View.IntersperseSurround(`this`.toIterable, start, sep, end))
45+
`this`.iterableFactory.from(new View.IntersperseSurround(`this`.toIterable, start, sep, end))
4646

4747
}

src/main/scala/strawman/collection/decorators/views.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ package decorators
44
/** Views used by decorators */
55
object View {
66

7-
case class Intersperse[A](underlying: Iterable[A], sep: A) extends View[A] {
7+
class Intersperse[A](underlying: Iterable[A], sep: A) extends View[A] {
88
def iterator(): Iterator[A] = underlying.iterator().intersperse(sep)
99

1010
override def knownSize: Int = if (underlying.knownSize > 0) (2 * underlying.knownSize - 1) else underlying.knownSize
1111
}
1212

13-
case class IntersperseSurround[A](underlying: Iterable[A], start: A, sep: A, end: A) extends View[A] {
13+
class IntersperseSurround[A](underlying: Iterable[A], start: A, sep: A, end: A) extends View[A] {
1414
def iterator(): Iterator[A] = underlying.iterator().intersperse(start, sep, end)
1515

1616
override def knownSize: Int =

0 commit comments

Comments
 (0)