Skip to content

Commit ba8807e

Browse files
authored
Merge pull request #24 from scala/sorted-sets-overloaded
Overloading based implementation of Set, TreeSet, Map and TreeMap
2 parents e134e98 + 1c137f5 commit ba8807e

File tree

18 files changed

+494
-15
lines changed

18 files changed

+494
-15
lines changed

src/main/scala/strawman/collection/Iterable.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ trait IterableLike[+A, +C[X] <: Iterable[X]]
3434
/** Create a collection of type `C[A]` from the elements of `coll`, which has
3535
* the same element type as this collection. Overridden in StringOps and ArrayOps.
3636
*/
37-
protected[this] def fromIterableWithSameElemType(coll: Iterable[A]): C[A] = fromIterable(coll)
37+
protected[this] def fromIterableWithSameElemType(coll: Iterable[A]): C[A]
3838
}
3939

4040
/** Base trait for instances that can construct a collection from an iterable */
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package strawman.collection
2+
3+
import strawman.collection.mutable.Builder
4+
5+
import scala.Option
6+
import scala.annotation.unchecked.uncheckedVariance
7+
import scala.Predef.???
8+
9+
/** Base Map type */
10+
trait Map[K, +V]
11+
extends Iterable[(K, V)]
12+
with MapLike[K, V, Map]
13+
14+
/** Base Map implementation type */
15+
trait MapLike[K, +V, +C[X, Y] <: Map[X, Y]]
16+
extends IterableLike[(K, V), Iterable]
17+
with IterableMonoTransforms[(K, V), C[K, V @uncheckedVariance]]
18+
with MapPolyTransforms[K, V, C] {
19+
20+
def get(key: K): Option[V]
21+
22+
}
23+
24+
/** Polymorphic transformation methods */
25+
trait MapPolyTransforms[K, +V, +C[X, Y] <: Map[X, Y]] extends IterablePolyTransforms[(K, V), Iterable] {
26+
27+
def map[K2, V2](f: (K, V) => (K2, V2)): C[K2, V2]
28+
29+
def flatMap[K2, V2](f: (K, V) => IterableOnce[(K2, V2)]): C[K2, V2]
30+
31+
}
32+
33+
/** Factory methods for collections of kind `* −> * -> *` */
34+
trait MapFactories[C[_, _]] {
35+
36+
def newBuilder[K, V]: Builder[(K, V), C[K, V]]
37+
38+
def empty[K, V]: C[K, V] =
39+
newBuilder[K, V].result
40+
41+
def apply[K, V](elems: (K, V)*): C[K, V] =
42+
newBuilder[K, V].++=(elems.toStrawman).result
43+
44+
}

src/main/scala/strawman/collection/Seq.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ trait SeqLike[+A, +C[X] <: Seq[X]]
5656

5757
protected def coll: C[A @uncheckedVariance]
5858

59+
protected[this] def fromIterableWithSameElemType(coll: Iterable[A]): C[A] = fromIterable(coll)
60+
5961
/** Do the elements of this collection are the same (and in the same order)
6062
* as those of `that`?
6163
*/

src/main/scala/strawman/collection/Set.scala

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,47 @@ package collection
44
import scala.{Any, Boolean, Equals, Int}
55
import scala.util.hashing.MurmurHash3
66

7+
8+
/** Base trait for set collections */
79
trait Set[A]
810
extends Iterable[A]
911
with SetLike[A, Set]
1012

13+
/** Base trait for set operations */
1114
trait SetLike[A, +C[X] <: Set[X]]
12-
extends SetOps[A]
15+
extends IterableLike[A, C]
16+
with SetMonoTransforms[A, C[A]]
1317
with Equals {
1418

1519
protected def coll: C[A]
1620

21+
def contains(elem: A): Boolean
22+
23+
def subsetOf(that: Set[A]): Boolean
24+
1725
def canEqual(that: Any) = true
1826

1927
override def equals(that: Any): Boolean =
2028
that match {
2129
case set: Set[A] =>
2230
(this eq set) ||
23-
(set canEqual this) &&
24-
(coll.size == set.size) &&
25-
(this subsetOf set)
31+
(set canEqual this) &&
32+
(coll.size == set.size) &&
33+
(this subsetOf set)
2634
case _ => false
2735
}
2836

2937
override def hashCode(): Int = Set.setHash(coll)
3038

3139
}
3240

33-
trait SetOps[A] extends Any {
41+
/** Monomorphic transformation operations */
42+
trait SetMonoTransforms[A, +Repr]
43+
extends IterableMonoTransforms[A, Repr] {
3444

35-
protected def coll: Set[A]
45+
def & (that: Set[A]): Repr
3646

37-
def subsetOf(that: Set[A]): Boolean
47+
def ++ (that: Set[A]): Repr
3848

3949
}
4050

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package strawman.collection
2+
3+
import strawman.collection.mutable.Builder
4+
5+
import scala.Ordering
6+
7+
/** Base trait for sorted collections */
8+
trait Sorted[A] extends SortedLike[A, Sorted[A]]
9+
10+
trait SortedLike[A, +Repr] {
11+
12+
def ordering: Ordering[A]
13+
14+
def range(from: A, until: A): Repr
15+
16+
}
17+
18+
/** Polymorphic transformation methods on sorted collections */
19+
trait SortedPolyTransforms[A, +C[X] <: Sorted[X]]
20+
extends IterablePolyTransforms[A, Iterable] {
21+
22+
def map[B](f: A => B)(implicit ordering: Ordering[B]): C[B]
23+
24+
}
25+
26+
/**
27+
* Factories for collections whose elements require an ordering
28+
*/
29+
trait OrderingGuidedFactories[C[_]] {
30+
31+
def builder[A](implicit ordering: Ordering[A]): Builder[A, C[A]]
32+
33+
def empty[A : Ordering]: C[A] = builder[A].result
34+
35+
def apply[A : Ordering](as: A*): C[A] = (builder[A] ++= as.toStrawman).result
36+
37+
}

src/main/scala/strawman/collection/View.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ trait View[+A] extends Iterable[A] with IterableLike[A, View] {
1313
case _ => View.fromIterator(c.iterator())
1414
}
1515
override def className = "View"
16+
17+
protected[this] def fromIterableWithSameElemType(coll: Iterable[A]): View[A] = fromIterable(coll)
18+
1619
}
1720

1821
/** This object reifies operations on views as case classes */
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package strawman.collection.immutable
2+
3+
import strawman.collection.{IterableFactory, Iterator}
4+
5+
import scala.Boolean
6+
import scala.Predef.???
7+
8+
/** An immutable Set backed by a hash trie */
9+
class HashSet[A] extends Set[A] with SetLike[A, HashSet] {
10+
11+
// From IterableOnce
12+
def iterator(): Iterator[A] = ???
13+
14+
// From IterablePolyTransforms
15+
def fromIterable[B](coll: strawman.collection.Iterable[B]): HashSet[B] = ???
16+
protected[this] def fromIterableWithSameElemType(coll: strawman.collection.Iterable[A]): HashSet[A] = fromIterable(coll)
17+
18+
// From SetLike
19+
def contains(elem: A): Boolean = ???
20+
def subsetOf(that: strawman.collection.Set[A]): Boolean = ???
21+
22+
// From SetMonoTransforms
23+
def & (that: strawman.collection.Set[A]): HashSet[A] = ???
24+
def ++ (that: strawman.collection.Set[A]): HashSet[A] = ???
25+
26+
// From immutable.SetLike
27+
def + (elem: A): HashSet[A] = ???
28+
def - (elem: A): HashSet[A] = ???
29+
30+
}
31+
32+
object HashSet extends IterableFactory[HashSet] {
33+
34+
def fromIterable[B](it: strawman.collection.Iterable[B]): HashSet[B] = ???
35+
36+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package strawman
2+
package collection.immutable
3+
4+
import strawman.collection.IterableMonoTransforms
5+
6+
/** Base type of immutable Maps */
7+
trait Map[K, +V]
8+
extends collection.Map[K, V]
9+
with MapLike[K, V, Map]
10+
11+
/** Base trait of immutable Maps implementations */
12+
trait MapLike[K, +V, +C[X, +Y] <: Map[X, Y]]
13+
extends collection.MapLike[K, V, C]
14+
with MapMonoTransforms[K, V, C[K, V]]
15+
with Iterable[(K, V)]
16+
17+
/** Immutable Map operations returning a self-like Map */
18+
trait MapMonoTransforms[K, +V, +Repr <: Map[K, V]]
19+
extends IterableMonoTransforms[(K, V), Repr] {
20+
21+
/**
22+
* Removes a key from this map, returning a new map.
23+
*
24+
* @param key the key to be removed
25+
* @return a new map without a binding for ''key''
26+
*/
27+
def - (key: K): Repr
28+
29+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package strawman
2+
package collection.immutable
3+
4+
/** Base trait for immutable set collections */
5+
trait Set[A]
6+
extends collection.Set[A]
7+
with Iterable[A]
8+
with SetLike[A, Set]
9+
10+
/** Base trait for immutable set operations */
11+
trait SetLike[A, +C[X] <: Set[X]]
12+
extends collection.SetLike[A, C]
13+
with SetMonoTransforms[A, C[A]]
14+
15+
/** Transformation operations returning a Set containing the same kind of
16+
* elements
17+
*/
18+
trait SetMonoTransforms[A, +Repr]
19+
extends collection.SetMonoTransforms[A, Repr] {
20+
21+
def + (elem: A): Repr
22+
23+
def - (elem: A): Repr
24+
25+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package strawman
2+
package collection.immutable
3+
4+
import strawman.collection.{IterablePolyTransforms, MapPolyTransforms, Sorted, SortedLike}
5+
6+
import scala.annotation.unchecked.uncheckedVariance
7+
import scala.Ordering
8+
9+
trait SortedMap[K, +V]
10+
extends Map[K, V]
11+
with Sorted[K]
12+
with SortedMapLike[K, V, SortedMap]
13+
14+
trait SortedMapLike[K, +V, +C[X, +Y] <: SortedMap[X, Y]]
15+
extends SortedLike[K, C[K, V]]
16+
with SortedMapPolyTransforms[K, V, C]
17+
with MapLike[K, V, Map] // Inherited Map operations can only return a `Map` because they don’t take an evidence `Ordering`
18+
with MapMonoTransforms[K, V, C[K, V]] // Operations that return the same collection type can return a `SortedMap`, though
19+
20+
/** Polymorphic transformation methods for sorted Maps */
21+
trait SortedMapPolyTransforms[K, +V, +C[X, Y] <: Sorted[X]]
22+
// We inherit polymorphic transformations returning an Iterable (e.g. to
23+
// support the following use case `kvs.map((k, v) => v)`)
24+
extends IterablePolyTransforms[(K, V), Iterable]
25+
// Then we also inherit polymorphic transformations returning a Map, just
26+
// to get inheritance linearization right and disambiguate between
27+
// overloaded methods
28+
with MapPolyTransforms[K, V, Map] {
29+
30+
// And finally, we add new overloads taking an ordering
31+
def map[K2, V2](f: (K, V) => (K2, V2))(implicit ordering: Ordering[K2]): C[K2, V2]
32+
33+
/**
34+
* Add a key/value pair to this map, returning a new map.
35+
*
36+
* @param kv the key/value pair.
37+
* @tparam V1 the type of the value in the key/value pair.
38+
* @return A new map with the new binding added to this map.
39+
*/
40+
def + [V1 >: V](kv: (K, V1)): C[K, V1]
41+
42+
}
43+

0 commit comments

Comments
 (0)