Skip to content

Commit

Permalink
Merge pull request scala#24 from scala/sorted-sets-overloaded
Browse files Browse the repository at this point in the history
Overloading based implementation of Set, TreeSet, Map and TreeMap
  • Loading branch information
julienrf authored Feb 23, 2017
2 parents e134e98 + 1c137f5 commit ba8807e
Show file tree
Hide file tree
Showing 18 changed files with 494 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/main/scala/strawman/collection/Iterable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ trait IterableLike[+A, +C[X] <: Iterable[X]]
/** Create a collection of type `C[A]` from the elements of `coll`, which has
* the same element type as this collection. Overridden in StringOps and ArrayOps.
*/
protected[this] def fromIterableWithSameElemType(coll: Iterable[A]): C[A] = fromIterable(coll)
protected[this] def fromIterableWithSameElemType(coll: Iterable[A]): C[A]
}

/** Base trait for instances that can construct a collection from an iterable */
Expand Down
44 changes: 44 additions & 0 deletions src/main/scala/strawman/collection/Map.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package strawman.collection

import strawman.collection.mutable.Builder

import scala.Option
import scala.annotation.unchecked.uncheckedVariance
import scala.Predef.???

/** Base Map type */
trait Map[K, +V]
extends Iterable[(K, V)]
with MapLike[K, V, Map]

/** Base Map implementation type */
trait MapLike[K, +V, +C[X, Y] <: Map[X, Y]]
extends IterableLike[(K, V), Iterable]
with IterableMonoTransforms[(K, V), C[K, V @uncheckedVariance]]
with MapPolyTransforms[K, V, C] {

def get(key: K): Option[V]

}

/** Polymorphic transformation methods */
trait MapPolyTransforms[K, +V, +C[X, Y] <: Map[X, Y]] extends IterablePolyTransforms[(K, V), Iterable] {

def map[K2, V2](f: (K, V) => (K2, V2)): C[K2, V2]

def flatMap[K2, V2](f: (K, V) => IterableOnce[(K2, V2)]): C[K2, V2]

}

/** Factory methods for collections of kind `* −> * -> *` */
trait MapFactories[C[_, _]] {

def newBuilder[K, V]: Builder[(K, V), C[K, V]]

def empty[K, V]: C[K, V] =
newBuilder[K, V].result

def apply[K, V](elems: (K, V)*): C[K, V] =
newBuilder[K, V].++=(elems.toStrawman).result

}
2 changes: 2 additions & 0 deletions src/main/scala/strawman/collection/Seq.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ trait SeqLike[+A, +C[X] <: Seq[X]]

protected def coll: C[A @uncheckedVariance]

protected[this] def fromIterableWithSameElemType(coll: Iterable[A]): C[A] = fromIterable(coll)

/** Do the elements of this collection are the same (and in the same order)
* as those of `that`?
*/
Expand Down
24 changes: 17 additions & 7 deletions src/main/scala/strawman/collection/Set.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,47 @@ package collection
import scala.{Any, Boolean, Equals, Int}
import scala.util.hashing.MurmurHash3


/** Base trait for set collections */
trait Set[A]
extends Iterable[A]
with SetLike[A, Set]

/** Base trait for set operations */
trait SetLike[A, +C[X] <: Set[X]]
extends SetOps[A]
extends IterableLike[A, C]
with SetMonoTransforms[A, C[A]]
with Equals {

protected def coll: C[A]

def contains(elem: A): Boolean

def subsetOf(that: Set[A]): Boolean

def canEqual(that: Any) = true

override def equals(that: Any): Boolean =
that match {
case set: Set[A] =>
(this eq set) ||
(set canEqual this) &&
(coll.size == set.size) &&
(this subsetOf set)
(set canEqual this) &&
(coll.size == set.size) &&
(this subsetOf set)
case _ => false
}

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

}

trait SetOps[A] extends Any {
/** Monomorphic transformation operations */
trait SetMonoTransforms[A, +Repr]
extends IterableMonoTransforms[A, Repr] {

protected def coll: Set[A]
def & (that: Set[A]): Repr

def subsetOf(that: Set[A]): Boolean
def ++ (that: Set[A]): Repr

}

Expand Down
37 changes: 37 additions & 0 deletions src/main/scala/strawman/collection/Sorted.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package strawman.collection

import strawman.collection.mutable.Builder

import scala.Ordering

/** Base trait for sorted collections */
trait Sorted[A] extends SortedLike[A, Sorted[A]]

trait SortedLike[A, +Repr] {

def ordering: Ordering[A]

def range(from: A, until: A): Repr

}

/** Polymorphic transformation methods on sorted collections */
trait SortedPolyTransforms[A, +C[X] <: Sorted[X]]
extends IterablePolyTransforms[A, Iterable] {

def map[B](f: A => B)(implicit ordering: Ordering[B]): C[B]

}

/**
* Factories for collections whose elements require an ordering
*/
trait OrderingGuidedFactories[C[_]] {

def builder[A](implicit ordering: Ordering[A]): Builder[A, C[A]]

def empty[A : Ordering]: C[A] = builder[A].result

def apply[A : Ordering](as: A*): C[A] = (builder[A] ++= as.toStrawman).result

}
3 changes: 3 additions & 0 deletions src/main/scala/strawman/collection/View.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ trait View[+A] extends Iterable[A] with IterableLike[A, View] {
case _ => View.fromIterator(c.iterator())
}
override def className = "View"

protected[this] def fromIterableWithSameElemType(coll: Iterable[A]): View[A] = fromIterable(coll)

}

/** This object reifies operations on views as case classes */
Expand Down
36 changes: 36 additions & 0 deletions src/main/scala/strawman/collection/immutable/HashSet.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package strawman.collection.immutable

import strawman.collection.{IterableFactory, Iterator}

import scala.Boolean
import scala.Predef.???

/** An immutable Set backed by a hash trie */
class HashSet[A] extends Set[A] with SetLike[A, HashSet] {

// From IterableOnce
def iterator(): Iterator[A] = ???

// From IterablePolyTransforms
def fromIterable[B](coll: strawman.collection.Iterable[B]): HashSet[B] = ???
protected[this] def fromIterableWithSameElemType(coll: strawman.collection.Iterable[A]): HashSet[A] = fromIterable(coll)

// From SetLike
def contains(elem: A): Boolean = ???
def subsetOf(that: strawman.collection.Set[A]): Boolean = ???

// From SetMonoTransforms
def & (that: strawman.collection.Set[A]): HashSet[A] = ???
def ++ (that: strawman.collection.Set[A]): HashSet[A] = ???

// From immutable.SetLike
def + (elem: A): HashSet[A] = ???
def - (elem: A): HashSet[A] = ???

}

object HashSet extends IterableFactory[HashSet] {

def fromIterable[B](it: strawman.collection.Iterable[B]): HashSet[B] = ???

}
29 changes: 29 additions & 0 deletions src/main/scala/strawman/collection/immutable/Map.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package strawman
package collection.immutable

import strawman.collection.IterableMonoTransforms

/** Base type of immutable Maps */
trait Map[K, +V]
extends collection.Map[K, V]
with MapLike[K, V, Map]

/** Base trait of immutable Maps implementations */
trait MapLike[K, +V, +C[X, +Y] <: Map[X, Y]]
extends collection.MapLike[K, V, C]
with MapMonoTransforms[K, V, C[K, V]]
with Iterable[(K, V)]

/** Immutable Map operations returning a self-like Map */
trait MapMonoTransforms[K, +V, +Repr <: Map[K, V]]
extends IterableMonoTransforms[(K, V), Repr] {

/**
* Removes a key from this map, returning a new map.
*
* @param key the key to be removed
* @return a new map without a binding for ''key''
*/
def - (key: K): Repr

}
25 changes: 25 additions & 0 deletions src/main/scala/strawman/collection/immutable/Set.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package strawman
package collection.immutable

/** Base trait for immutable set collections */
trait Set[A]
extends collection.Set[A]
with Iterable[A]
with SetLike[A, Set]

/** Base trait for immutable set operations */
trait SetLike[A, +C[X] <: Set[X]]
extends collection.SetLike[A, C]
with SetMonoTransforms[A, C[A]]

/** Transformation operations returning a Set containing the same kind of
* elements
*/
trait SetMonoTransforms[A, +Repr]
extends collection.SetMonoTransforms[A, Repr] {

def + (elem: A): Repr

def - (elem: A): Repr

}
43 changes: 43 additions & 0 deletions src/main/scala/strawman/collection/immutable/SortedMap.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package strawman
package collection.immutable

import strawman.collection.{IterablePolyTransforms, MapPolyTransforms, Sorted, SortedLike}

import scala.annotation.unchecked.uncheckedVariance
import scala.Ordering

trait SortedMap[K, +V]
extends Map[K, V]
with Sorted[K]
with SortedMapLike[K, V, SortedMap]

trait SortedMapLike[K, +V, +C[X, +Y] <: SortedMap[X, Y]]
extends SortedLike[K, C[K, V]]
with SortedMapPolyTransforms[K, V, C]
with MapLike[K, V, Map] // Inherited Map operations can only return a `Map` because they don’t take an evidence `Ordering`
with MapMonoTransforms[K, V, C[K, V]] // Operations that return the same collection type can return a `SortedMap`, though

/** Polymorphic transformation methods for sorted Maps */
trait SortedMapPolyTransforms[K, +V, +C[X, Y] <: Sorted[X]]
// We inherit polymorphic transformations returning an Iterable (e.g. to
// support the following use case `kvs.map((k, v) => v)`)
extends IterablePolyTransforms[(K, V), Iterable]
// Then we also inherit polymorphic transformations returning a Map, just
// to get inheritance linearization right and disambiguate between
// overloaded methods
with MapPolyTransforms[K, V, Map] {

// And finally, we add new overloads taking an ordering
def map[K2, V2](f: (K, V) => (K2, V2))(implicit ordering: Ordering[K2]): C[K2, V2]

/**
* Add a key/value pair to this map, returning a new map.
*
* @param kv the key/value pair.
* @tparam V1 the type of the value in the key/value pair.
* @return A new map with the new binding added to this map.
*/
def + [V1 >: V](kv: (K, V1)): C[K, V1]

}

15 changes: 15 additions & 0 deletions src/main/scala/strawman/collection/immutable/SortedSet.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package strawman.collection.immutable

import strawman.collection.{Sorted, SortedLike, SortedPolyTransforms}

/** Base trait for sorted sets */
trait SortedSet[A]
extends Set[A]
with Sorted[A]
with SortedSetLike[A, SortedSet] // Inherited SortedSet operations return a `SortedSet`

trait SortedSetLike[A, +C[X] <: SortedSet[X]]
extends SortedLike[A, C[A]]
with SortedPolyTransforms[A, C]
with SetLike[A, Set] // Inherited Set operations return a `Set`
with SetMonoTransforms[A, C[A]] // Override the return type of Set ops to return C[A]
40 changes: 40 additions & 0 deletions src/main/scala/strawman/collection/immutable/TreeMap.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package strawman
package collection.immutable

import strawman.collection.SortedLike

import scala.{Option, Ordering}
import scala.Predef.???

final class TreeMap[K, +V]
extends SortedMap[K, V]
with SortedMapLike[K, V, TreeMap] {

// Members declared in collection.IterableLike
protected[this] def fromIterableWithSameElemType(coll: collection.Iterable[(K, V)]): TreeMap[K, V] = ???

// Members declared in collection.IterableOnce
def iterator(): collection.Iterator[(K, V)] = ???

// Members declared in collection.IterablePolyTransforms
def fromIterable[B](coll: collection.Iterable[B]): collection.immutable.Iterable[B] = ???

// Members declared in collection.MapLike
def get(key: K): Option[V] = ???

// Members declared in collection.immutable.MapMonoTransforms
def -(key: K): TreeMap[K,V] = ???
def +[V1 >: V](kv: (K, V1)): TreeMap[K,V1] = ???

// Members declared in collection.MapPolyTransforms
def flatMap[K2, V2](f: (K, V) => collection.IterableOnce[(K2, V2)]): collection.immutable.Map[K2,V2] = ???
def map[K2, V2](f: (K, V) => (K2, V2)): collection.immutable.Map[K2,V2] = ???

// Members declared in collection.SortedMapPolyTransforms
def map[K2, V2](f: (K, V) => (K2, V2))(implicit ordering: Ordering[K2]): collection.immutable.TreeMap[K2,V2] = ???

// Members declared in collection.SortedLike
def ordering: Ordering[K] = ???
def range(from: K,until: K): TreeMap[K,V] = ???

}
Loading

0 comments on commit ba8807e

Please sign in to comment.