Alternative collections API for Scala / changeset
| author | david@mel |
| Sat Apr 19 21:51:39 2008 +0100 (8 months ago) | |
| changeset 4 | 95de4825215f |
| parent 3 | e63ca8b0db7e |
| child 5 | 678d2f9ce2ff |
Changed the structure of Buildable as per Jamie Webb's excellent suggestion.
Added a "Buffer" type - basically an immutable slice of an array.
Added a "Buffer" type - basically an immutable slice of an array.
| src/buildable.scala | file | annotate | diff | revisions | |
| src/sequence/list.scala | file | annotate | diff | revisions | |
| src/traversable.scala | file | annotate | diff | revisions |
--- a/src/buildable.scala Sat Apr 19 16:58:18 2008 +0100+++ b/src/buildable.scala Sat Apr 19 21:51:39 2008 +0100@@ -4,16 +4,10 @@ import mutable._;import mutable._;import sequence._;import List.List;--trait Builder[I[_], T]{- def += (t : T) : Unit;- def ++= (ts : T*) = for (t <- ts) { this += t }- def build : I[T];-}+import traversable._;trait Buildable[I[_], T]{- def builder () : Builder[I, T]- def builderOfCapacity(n : Int) : Builder[I, T ] = builder();+ def build(contents : Traversable[T]) : I[T];}/**@@ -23,31 +17,30 @@ object Building{implicit def listIsBuildable[T] : Buildable[List, T] = List.buildableimplicit def scalaListIsBuildable[T] : Buildable[scala.List, T] = new Buildable[scala.List, T]{- def builder () = new Builder[scala.List, T]{- val buffer = new ListBuffer[T]();- def += (t : T) = buffer += t;- def build = buffer.toList;- }- }-- implicit def immutableSetIsBuildable[T] = new Buildable[immutable.Set, T]{- def builder () = new Builder[immutable.Set, T]{- val buffer = new ListBuffer[T]();- def += (t : T) = buffer += t;- def build = immutable.Set(buffer.toList :_*);+ def build (contents : Traversable[T]) = {+ val buffer = new ListBuffer[T];+ contents.foreach(buffer += (_ : T));+ buffer.toList;}}implicit def arrayIsBuildable[T] = new Buildable[Array, T]{- class ArrayBuilder(buffer : ArrayBuffer[T]) extends Builder[Array, T]{- def += (t : T) = (buffer += t);- def build = buffer.toArray;- }-- def builder () = new ArrayBuilder(new ArrayBuffer[T])- override def builderOfCapacity(n : Int) = new ArrayBuilder(new ArrayBuffer[T]{- ensureSize(n);- });+ def build(contents : Traversable[T]) = contents.knownSize match {+ case Some(i) => {+ val result = new Array[T](i);+ var j = 0;+ contents.foreach(x => {+ result(j) = x;+ j = j + 1;+ })+ result;+ }+ case None => {+ val buffer = new ArrayBuffer[T];+ contents.foreach(x => buffer += x);+ buffer.toArray;+ }+ }}}
--- a/src/sequence/list.scala Sat Apr 19 16:58:18 2008 +0100+++ b/src/sequence/list.scala Sat Apr 19 21:51:39 2008 +0100@@ -9,7 +9,11 @@ object List extends SequenceType{type I[+T] = List[T];def buildable[T] : Buildable[List, T] = new Buildable[List, T]{- def builder() = new ListBuilder[T];+ def build(contents : Traversable[T]) = {+ var rev : List[T] = Nil;+ contents.foreach(x => rev = x +: rev);+ rev.reverse;+ }}def empty = Nil@@ -63,12 +67,6 @@ object List extends SequenceType{def ++[S >: T](that : List[S]) : List[S] = reverse.reversePrepend(that);}- class ListBuilder[T] extends Builder[List, T]{- var built : List[T] = Nil;- def +=(t : T) = built = t +: built;- def build : List[T] = built.reverse;- }-case class Cons[+T](head : T, tail : List[T]) extends List[T]{override def isEmpty = false;val length = 1 + tail.length;
--- a/src/traversable.scala Sat Apr 19 16:58:18 2008 +0100+++ b/src/traversable.scala Sat Apr 19 21:51:39 2008 +0100@@ -22,6 +22,7 @@ trait Traversable[+T]{new Traversable[S]{def traverse(g : S => Unit) = outer.traverse(g.compose(f));override def map[R](g : S => R) = outer.map(g.compose(f));+ override def knownSize = outer.knownSize;}}@@ -43,11 +44,7 @@ trait Traversable[+T]{def exists(f : T => Boolean) : Boolean = !filter(f).isEmptydef forall(f : T => Boolean) : Boolean = !exists(x => !f(x));- def as[M[_], S >: T](implicit buildable : Buildable[M, S]) : M[S] = {- val builder = buildable.builder;- foreach(x => builder += x);- builder.build;- }+ def as[M[_], S >: T](implicit buildable : Buildable[M, S]) : M[S] = buildable.build(this);def intersperse[S >: T](t : S) = {val outer = this;@@ -64,7 +61,7 @@ trait Traversable[+T]{}def take(i : Int) : Traversable[T] = {- val outer = this;+ val outer = this;new Traversable[T]{def traverse(f : T => Unit) {var j = i;@@ -77,13 +74,16 @@ trait Traversable[+T]{})}+ override def knownSize = outer.knownSize.map(j => Math.min(i, j));override def take(j : Int) = outer.take(Math.min(i, j));}}def drop(dropped : Int) : Traversable[T] = {val outer = this;- new Traversable[T]{++ if (knownSize.map(x => x < dropped).getOrElse(false)) Traversable.empty+ else new Traversable[T]{def traverse(f : T => Unit) {var i = 0;outer.traverse(x => {@@ -91,9 +91,13 @@ trait Traversable[+T]{else i = i + 1;});}++ override def knownSize = outer.knownSize.map(n => n - dropped);}}++ def knownSize : Option[Int] = None;def takeWhile(f : T => Boolean) : Traversable[T] = {val outer = this;@@ -101,8 +105,23 @@ trait Traversable[+T]{def traverse(g : T => Unit) {outer.traverse(x => if (!f(x)) break else g(x));}+ }+ }- override def takeWhile(g : T => Boolean) = outer.takeWhile(x => f(x) && g(x));+ def dropWhile(f : T => Boolean) : Traversable[T] = {+ val outer = this;+ new Traversable[T]{+ def traverse(g : T => Unit) {+ var seen = false;+ outer.traverse(x => if (seen || !f(x)) { seen = true; g(x) });+ }+ }+ }++ def concat[S >: T](that : Traversable[S]) : Traversable[S] = {+ val outer = this;+ new Traversable[S]{+ def traverse(g : S => Unit) { outer.traverse(g); that.traverse(g); }}}@@ -134,8 +153,13 @@ trait Traversable[+T]{}object Traversable{- def fromIterable[T](it : Iterable[T]) = new Traversable[T]{+ implicit def fromIterable[T](it : Iterable[T]) = new Traversable[T]{def traverse(f : T => Unit) = it.foreach(f);++ override def knownSize = it match {+ case (it : Collection[_]) => Some(it.size);+ case _ => None;+ }}val empty = new Traversable[Nothing]{
