Alternative collections API for Scala / changeset
| author | David R. MacIver@DRM-DESKTOP.trampolan |
| Wed May 21 13:44:53 2008 +0100 (7 months ago) | |
| changeset 11 | 8c43eeabda7c |
| parent 10 | 53f65c4f9249 |
| child 12 | c8920a9d795d |
Trimming leftover files. Still not quite used to hg.
--- a/pertests.scala Mon Apr 21 11:14:34 2008 +0100+++ /dev/null Thu Jan 01 00:00:00 1970 +0000@@ -1,21 +0,0 @@-import alt.collections._-import traversable._-import buildable.Building._;--def time(action : => Unit) = { val start = System.currentTimeMillis(); action; System.currentTimeMillis() - start }--def foo (n : Int) = List.range(1, n).map( (_ : Int) * 2);-def bar(n : Int) = Traversable.fromIterable(List.range(1, n)).map((_ : Int) * 2).as[List, Int]--val size = 100000;--var myWay = 0L;-var standardWay = 0L;--for (i <- 0 until 10) {- standardWay = standardWay + time(foo(size));- myWay = myWay + time(bar(size));-}--println("My way: " + myWay);-println("Standard way: " + standardWay);
--- a/src/buildable.scala Mon Apr 21 11:14:34 2008 +0100+++ /dev/null Thu Jan 01 00:00:00 1970 +0000@@ -1,46 +0,0 @@-package alt.collections.buildable;--import scala.collection._;-import mutable._;-import sequence._;-import List.List;-import traversable._;--trait Buildable[I[_], T]{- def build(contents : Traversable[T]) : I[T];-}--/**- * Defines a type class for generic building of collections.- */-object Building{- implicit def listIsBuildable[T] : Buildable[List, T] = List.buildable-- implicit def scalaListIsBuildable[T] : Buildable[scala.List, T] = new Buildable[scala.List, T]{- def build (contents : Traversable[T]) = {- val buffer = new ListBuffer[T];- contents.foreach(buffer += (_ : T));- buffer.toList;- }- }-- implicit def arrayIsBuildable[T] = new Buildable[Array, T]{- 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/list.scala Mon Apr 21 11:14:34 2008 +0100+++ /dev/null Thu Jan 01 00:00:00 1970 +0000@@ -1,56 +0,0 @@-package alt.collections;-import traversable._;-import buildable._;--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 ::[+T](head : T, tail : List[T]) extends List[T]{- override def isEmpty = false;- val length = 1 + tail.length;-}--case object Nil extends List[Nothing]{- override def isEmpty = true;- def head = error("Nil.head");- def tail = error("Nil.tail");- def length = 0;-}--sealed abstract class List[+T] extends Traversable[T]{- def length : Int;- override def isEmpty : Boolean;- def head : T;- def tail : List[T];-- def ::[S >: T](t : S) : List[S] = new alt.collections.::(t, this);-- def traverse(f : T => Unit) = if (!isEmpty) { f(head); tail.traverse(f); } else ()-- override final def equals(that : Any) : Boolean = that match {- case (that : List[_]) => if (that.isEmpty != this.isEmpty) false;- else if (this.isEmpty) true;- else if (this.head != that.head) false;- else this.tail.equals(that.tail);-- case _ => false;- }-- override final def hashCode = hash(0);-- private def hash(h : Int) : Int = if (isEmpty) h;- else tail.hash(31 * h + head.hashCode);-- override def toString = withName("List");-- final def reversePrepend[S >: T](that : List[S]) : List[S] =- if (isEmpty) that;- else tail.reversePrepend(head :: that);-- def reverse : List[T] = reversePrepend(Nil);-- def ++[S >: T](that : List[S]) : List[S] = reverse.reversePrepend(that);-}
--- a/src/main/scala/map/intmap.scala Mon Apr 21 11:14:34 2008 +0100+++ /dev/null Thu Jan 01 00:00:00 1970 +0000@@ -1,54 +0,0 @@-package alt.collections.map;--import alt.collections.traversable._;-import alt.collections.buildable._;--// Extremely unoptimised immutable IntMap implementation.-// About the simplest possible thing you could do-class IntMap extends MapType[Int]{--- class IntMap[+V] private (contents : MapNode) extends Map[V]{- def traverse(f : ((K, V)) => Unit) = {-- }-- }-}--object MapNode{- val chunkSize = 4;- val arraySize = 1 << chunkSize;- val mask = arraySize - 1;-}--private class MapNode(val value : Any, val children : Array[MapNode]){- import MapNode._;-- def this() = this(null, null);-- val get(key : Int) : Any =- if (key == 0) value;- else {- val chunk = key && mask;- if (!hasChild(chunk)) null;- else {- children(chunk).get(key >> chunkSize);- }- }-- def hasChild(chunk : Int) = (children != null && children(chunk) != null);-- def put(key : Int, value : Any) : MapNode = {- if (key == 0) new MapNode(value, children);- else {- val chunk = key && mask;- val newchildren = Array(children :_*);- if (newchildren(chunk) == null){- newchildren(chunk) = new MapNode();- }- newchildren(chunk) = newchildren(chunk).put(key >> chunkSize, value);- new MapNode(this.value, newchildren);- }- }-}
--- a/src/main/scala/sequence/fingertree.scala Mon Apr 21 11:14:34 2008 +0100+++ /dev/null Thu Jan 01 00:00:00 1970 +0000@@ -1,19 +0,0 @@-package alt.collections.sequence;--object FingerTree{- type I[+T] = FingerTree[T];-- def empty = Empty;--- private case object Empty extends FingerTree[Nothing];- private case class Single[+T](t : T) extends FingerTree[Nothing];- private case class Deep[T](left : T, center : FingerTree[Buffer[T]], right : T)(val size : Int);-- sealed abstract class FingerTree[+T] extends Sequence[T]{-- }----}
--- a/src/sequence/buffer.scala Mon Apr 21 11:14:34 2008 +0100+++ /dev/null Thu Jan 01 00:00:00 1970 +0000@@ -1,80 +0,0 @@-package alt.collections.sequence;--import buildable._;-import Building._;-import traversable._;--object Buffer extends SequenceType{- type I[+T] = Buffer[T];-- private def oob(msg : String) = throw new IndexOutOfBoundsException(msg);-- val empty = new Buffer[Nothing](null, 0, 0);-- def buildable[T] = new Buildable[Buffer, T] {- def build(c : Traversable[T]) = c match{- case (x : Buffer[T]) => x;- case _ => new Buffer[T](c.map(_.asInstanceOf[AnyRef]).as[Array, AnyRef]);- }- }-- class Buffer[+T] private[sequence] (var contents : Array[AnyRef], // Monomorphic for performance reasons. :(- val from : Int,- val to : Int) extends Sequence[T]{- private[sequence] def this(contents : Array[AnyRef]) = this(contents, 0, contents.length);-- if (from > to) oob("from > to");- def length = to - from;-- def trim : Buffer[T] = { contents = contents.slice(from, to).force; this }-- def apply(i : Int) = contents(adjust(i)).asInstanceOf[T];-- def traverse(f : T => Unit) = Traversable.range(from, to).map(contents).foreach(x => f(x.asInstanceOf[T]));-- def :+[S >: T](s : S) = {- if (to < contents.length && (s.asInstanceOf[AnyRef] eq contents(to))) new Buffer[T](contents, from, to + 1);- else {- val newcontents = new Array[AnyRef](length + 1);- contents.slice(from, to).copyToArray(newcontents, 0);- newcontents(length) = s.asInstanceOf[AnyRef];- new Buffer[S](newcontents);- }- }-- def +:[S >: T](s : S) = {- if (from > 0 && (s.asInstanceOf[AnyRef] eq contents(from - 1))) new Buffer[T](contents, from - 1, to);- else {- val newcontents = new Array[AnyRef](length + 1);- contents.slice(from, to).copyToArray(newcontents, 1);- newcontents(0) = s.asInstanceOf[AnyRef];- new Buffer[S](newcontents);- }- }-- def ++[S >: T](that : Buffer[S]) = {- if ((contents == that.contents) && (to == that.from)) new Buffer[S](contents, from, that.to);- else {- val newcontents = new Array[AnyRef](that.to - from);- contents.slice(from, to).copyToArray(newcontents, 0);- that.contents.slice(that.from, that.to).copyToArray(newcontents, length);- new Buffer[S](newcontents);- }- }-- override def drop(i : Int) =- if (i >= length) empty;- else new Buffer[T](contents, from + i, to);-- override def take(i : Int) =- if (i >= length) this;- else new Buffer[T](contents, from, from + i);-- private def adjust(i : Int) = {- if (i < 0) oob(i + " < 0");- val index = i + from;- if (index >= to) oob(i + " > " + length );- index;- }- }-}
--- a/src/sequence/list.scala Mon Apr 21 11:14:34 2008 +0100+++ /dev/null Thu Jan 01 00:00:00 1970 +0000@@ -1,84 +0,0 @@-package alt.collections.sequence;--import alt.collections._;-import traversable._;-import buildable._;---object List extends SequenceType{- type I[+T] = List[T];-- def buildable[T] : Buildable[List, T] = new Buildable[List, T]{- def build(contents : Traversable[T]) = contents match {- case (contents : List[T]) => contents;- case _ => {- var rev : List[T] = Nil;- contents.foreach(x => rev = x +: rev);- rev.reverse;- }- }- }-- def empty = Nil-- sealed abstract class List[+T] extends Sequence[T]{- def length : Int;- override def isEmpty : Boolean;- def head : T;- def tail : List[T];-- def apply(i : Int) = drop(i).head;-- def +:[S >: T](t : S) : List[S] = Cons(t, this);- def :+[S >: T](t : S) : List[S] = reversePrepend(singleton(t));-- def traverse(f : T => Unit) = if (!isEmpty) { f(head); tail.traverse(f); } else ()-- override final def equals(that : Any) : Boolean =- if (this eq that.asInstanceOf[AnyRef]) true- else that match {- case (that : List[_]) => if (that.length != this.length) false;- else if (this.isEmpty) true;- else if (this.head != that.head) false;- else this.tail.equals(that.tail);-- case _ => false;- }-- override final def hashCode = hash(0);-- def tails : Traversable[List[T]] = new Traversable[List[T]]{- def traverse(f : List[T] => Unit) = traverseTails(f);- }-- def traverseTails(f : List[T] => Unit) { if (!isEmpty) { f(this); tail.traverseTails(f); } else (); }-- override def drop(n : Int) : List[T] = if (n == 0 || isEmpty) this;- else tail.drop(n - 1);-- private def hash(h : Int) : Int = if (isEmpty) h;- else tail.hash(31 * h + head.hashCode);-- override def toString = withName("List");-- final def reversePrepend[S >: T](that : List[S]) : List[S] =- if (isEmpty) that;- else tail.reversePrepend(head +: that);-- def reverse : List[T] = reversePrepend(Nil);-- def ++[S >: T](that : List[S]) : List[S] = reverse.reversePrepend(that);- }-- case class Cons[+T](head : T, tail : List[T]) extends List[T]{- override def isEmpty = false;- val length = 1 + tail.length;- }-- case object Nil extends List[Nothing]{- override def isEmpty = true;- def head = error("Nil.head");- def tail = error("Nil.tail");- def length = 0;- }-}
--- a/src/sequence/sequence.scala Mon Apr 21 11:14:34 2008 +0100+++ /dev/null Thu Jan 01 00:00:00 1970 +0000@@ -1,38 +0,0 @@-package alt.collections.sequence;--import buildable._;-import Building._;-import traversable._;-import Traversable._;--trait SequenceType{- type I[+T] <: Sequence[T];-- def empty : I[Nothing];- def singleton[T] (t : T) : I[T] = t +: empty;- def tabulate[T](from : Int, to : Int, f : Int => T) : I[T] = Traversable.range(from, to).map(f).as[I, T]-- implicit def buildable[T] : Buildable[I, T]-- trait Sequence[+T] extends Traversable[T]{- def zip[S](that : SequenceType#Sequence[S]) = {- val length = Math.min(this.length, that.length);- this.take(length).as[Array, T].zip(that.take(length).as[Array,S]).as[I, (T, S)]- }- def apply(i : Int) : T;- def length : Int;- def ++[S >: T](that : I[S]) : I[S];- def :+[S >: T](x : S) : I[S];- def +:[S >: T](x : S) : I[S];-- override def knownSize = Some(length);-- /**- * Create the subsequence with indices [from, to).- * In the event that either from or to are outside the range- * of indices provided, this should return as much as is available.- */- def slice(from : Int, to : Int) : I[T] = drop(from).take(to - from).as[I, T]- def split(at : Int) : Product3[I[T], T, I[T]] = (slice(0, at), this(at), slice(at + 1, length));- }-}
--- a/src/traversable.scala Mon Apr 21 11:14:34 2008 +0100+++ /dev/null Thu Jan 01 00:00:00 1970 +0000@@ -1,206 +0,0 @@-package alt.collections.traversable;--import buildable._;-import scala.collection._;-import mutable._;-import Building._;-import Traversable._;--trait Traversable[+T]{- final def foreach(f : T => Unit) : Unit = {- try{- traverse(f);- } catch {- case Break => ();- }- }-- def traverse(f : T => Unit) : Unit;-- def map[S](f : T => S) : Traversable[S] = {- val outer = this;- 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;- }- }-- def filter(f : T => Boolean) : Traversable[T] = {- val outer = this;- new Traversable[T]{- def traverse(g : T => Unit) = outer.traverse( x => if (f(x)) g(x) )- override def filter(g : T => Boolean) = outer.filter(x => f(x) && g(x));- }- }-- def flatMap[S](f : T => Traversable[S]) : Traversable[S] = {- val outer = this;- new Traversable[S]{- def traverse(g : S => Unit) = outer.traverse(x => f(x).traverse(g));- }- }-- def exists(f : T => Boolean) : Boolean = !filter(f).isEmpty- def forall(f : T => Boolean) : Boolean = !exists(x => !f(x));-- def as[M[_], S >: T](implicit buildable : Buildable[M, S]) : M[S] = buildable.build(this);-- def intersperse[S >: T](t : S) = {- val outer = this;- new Traversable[S]{- def traverse(f : S => Unit){- var started = false;- outer.traverse(x => {- if (started) f(t);- else started = true;- f(x);- })- }- }- }-- def take(i : Int) : Traversable[T] = {- val outer = this;- new Traversable[T]{- def traverse(f : T => Unit) {- var j = i;- outer.traverse(x => {- if (j <= 0) break;- else {- j = j - 1;- f(x);- }- })- }-- 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;-- 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 => {- if (i >= dropped) f(x);- 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;- new Traversable[T]{- def traverse(g : T => Unit) {- outer.traverse(x => if (!f(x)) break else 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); }- }- }-- def isEmpty = {- var empty = true;- foreach(x => {empty = false; break});- empty;- }-- def foldLeft[S](s : S)(f : (S, T) => S) : S = {- var result = s;- foreach(x => { result = f(result, x) })- result;- }-- def mkString : String = {- val builder = new StringBuilder;- foreach(builder.append(_ : Any));- builder.toString- }-- def withName(name : String) : String = {- val builder = new StringBuilder();- builder.append(name).append("(");- intersperse(", ").foreach(builder.append(_ : Any));- builder.append(")");- builder.toString;- }-}--object Traversable{- 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]{- def traverse(f : Nothing => Unit) { }- }-- /**- * Creates the traversal which traverse start, f(start), f(f(start)),..- *- * f is allowed to break to terminate the iteration.- */- def iterate[T](start : T, f : T => T) = new Traversable[T]{- def traverse(g : T => Unit) = {- var last = start;- while(true) {- g(last);- last = f(last);- }- }- }-- def range(from : Int, until : Int) : Traversable[Int] =- if (from >= until) empty- else new Traversable[Int]{- def traverse(f : Int => Unit) = {- var i = from;- while (i < until){- f(i);- i = i + 1;- }- }-- override def take(n : Int) = range(from, Math.min(from + n, until));- override def drop(n : Int) = range(from + n, until);- }-- def break = throw Break;-}--private object Break extends Error{- override def fillInStackTrace = null;-}--
