summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-02-14 13:36:31 +0000
committerMartin Odersky <odersky@gmail.com>2003-02-14 13:36:31 +0000
commit23d2bfbeb21f63d82ed46d5b1b0b85b1ed2f4355 (patch)
tree08eeac303430a2e9a8280cb20ccd52207d948406
parent073294fbbaf752ed4f9005eb9421b7bd4f475173 (diff)
downloadscala-23d2bfbeb21f63d82ed46d5b1b0b85b1ed2f4355.tar.gz
scala-23d2bfbeb21f63d82ed46d5b1b0b85b1ed2f4355.tar.bz2
scala-23d2bfbeb21f63d82ed46d5b1b0b85b1ed2f4355.zip
Initial version.
-rw-r--r--sources/scala/$colon$colon.scala12
-rw-r--r--sources/scala/Cell.scala3
-rw-r--r--sources/scala/ConsStreamClass.scala13
-rw-r--r--sources/scala/EmptyStream.scala9
-rw-r--r--sources/scala/Iterator.scala35
-rw-r--r--sources/scala/List.scala345
-rw-r--r--sources/scala/Monitor.scala15
-rw-r--r--sources/scala/Nil.scala13
-rw-r--r--sources/scala/None.scala6
-rw-r--r--sources/scala/Option.scala21
-rw-r--r--sources/scala/Predef.scala48
-rw-r--r--sources/scala/Some.scala6
-rw-r--r--sources/scala/Stream.scala117
-rw-r--r--sources/scala/Tuple1.scala24
-rw-r--r--sources/scala/Tuple2.scala24
-rw-r--r--sources/scala/Tuple3.scala24
-rw-r--r--sources/scala/Tuple4.scala24
-rw-r--r--sources/scala/Tuple5.scala24
-rw-r--r--sources/scala/Tuple6.scala24
-rw-r--r--sources/scala/Tuple7.scala24
-rw-r--r--sources/scala/Tuple8.scala24
-rw-r--r--sources/scala/Tuple9.scala24
22 files changed, 859 insertions, 0 deletions
diff --git a/sources/scala/$colon$colon.scala b/sources/scala/$colon$colon.scala
new file mode 100644
index 0000000000..be2baedf5e
--- /dev/null
+++ b/sources/scala/$colon$colon.scala
@@ -0,0 +1,12 @@
+package scala {
+
+ /* A non empty list.
+ *
+ */
+ final case class ::[b](hd: b, tl: List[b]) extends List[b] with {
+ def isEmpty = False;
+ def head = hd;
+ def tail = tl;
+ override def toString(): String = mkString("[", ",", "]");
+ }
+}
diff --git a/sources/scala/Cell.scala b/sources/scala/Cell.scala
new file mode 100644
index 0000000000..4a6566c563
--- /dev/null
+++ b/sources/scala/Cell.scala
@@ -0,0 +1,3 @@
+package scala with {
+ case class Cell[T](elem: T)
+} \ No newline at end of file
diff --git a/sources/scala/ConsStreamClass.scala b/sources/scala/ConsStreamClass.scala
new file mode 100644
index 0000000000..a8f6d46e73
--- /dev/null
+++ b/sources/scala/ConsStreamClass.scala
@@ -0,0 +1,13 @@
+package scala;
+
+final class ConsStreamClass[b](hd: b, tl: () => Stream[b]) extends Stream[b] with {
+ def isEmpty = False;
+ def head = hd;
+ private var tlVal: Stream[b] = null;
+ private var tlDefined: Boolean = False;
+ def tail: Stream[b] = {
+ if (!tlDefined) { tlVal = tl(); tlDefined = True; }
+ tlVal
+ }
+ override def toString(): String = "ConsStream(" + hd + ", ?)";
+}
diff --git a/sources/scala/EmptyStream.scala b/sources/scala/EmptyStream.scala
new file mode 100644
index 0000000000..de7f0e025e
--- /dev/null
+++ b/sources/scala/EmptyStream.scala
@@ -0,0 +1,9 @@
+package scala;
+
+final class EmptyStream[c]() extends Stream[c] with {
+ def isEmpty = True;
+ def head: c = error("head of empty stream");
+ def tail: Stream[c] = error("tail of empty stream");
+ override def toString(): String = "EmptyStream";
+}
+
diff --git a/sources/scala/Iterator.scala b/sources/scala/Iterator.scala
new file mode 100644
index 0000000000..f5ef4b0f0b
--- /dev/null
+++ b/sources/scala/Iterator.scala
@@ -0,0 +1,35 @@
+package scala {
+
+trait Iterator[a] {
+ def hasNext: Boolean;
+ def next: a;
+ def filter(p: a => Boolean): Iterator[a] = new BufferedIterator[a] with {
+ private val source = new Buffered(Iterator.this);
+ private def skip: Unit = while (source.hasNext && !p(source.head)) { source.next; () }
+ def hasNext: Boolean = { skip; source.hasNext }
+ def next: a = { skip; source.next }
+ def head: a = { skip; source.head; }
+ }
+}
+
+trait BufferedIterator[a] extends Iterator[a] {
+ def head: a;
+}
+
+class Buffered[a](it: Iterator[a]) extends Iterator[a] {
+ private var hd: a = _;
+ private var ahead: Boolean = False;
+ def head: a = {
+ if (!ahead) { hd = it.next; ahead = True }
+ hd
+ }
+ def next: a =
+ if (ahead) { ahead = False; hd }
+ else head;
+
+ def hasNext: Boolean =
+ ahead || it.hasNext;
+}
+}
+
+
diff --git a/sources/scala/List.scala b/sources/scala/List.scala
new file mode 100644
index 0000000000..d1b04319f5
--- /dev/null
+++ b/sources/scala/List.scala
@@ -0,0 +1,345 @@
+package scala {
+
+ /* An abstract class representing an ordered collection of elements
+ * of type <code>a</code>.
+ * This class comes with two implementing case classes {link scala.Nil/} and
+ * {@link scala.::_class/} that implement the abstract members <code>isEmpty</code>,
+ * <code>head</code> and <code>tail</code>. But instead of this
+ *
+ * @arg a the type of the elements contained in the list.
+ */
+ trait List[a] {
+
+ /** Tests if this list is empty.
+ * @return True iff the list contains no element.
+ */
+ def isEmpty: Boolean;
+
+ /** Returns this first element of the list.
+ * @return the first element of this list.
+ * @throws java.lang.RuntimeException if the list is empty.
+ */
+ def head: a;
+
+ /** Returns this list without its first element.
+ * @return this list without its first element.
+ * @throws java.lang.RuntimeException if the list is empty.
+ */
+ def tail: List[a];
+
+ /** Throws a runtime exception with output message <code>x</code>. This method
+ * is used to signal an error.
+ * @param x message to be displayed.
+ * @throws java.lang.RuntimeException with the given message <code>x</code>.
+ */
+ protected def error[a](x: String):a = (new java.lang.RuntimeException(x)).throw;
+
+ /** Add an element <code>x</code> at the beginning of this list.
+ * <p>
+ * Ex:<br>
+ * <code>1 :: [2, 3] = [2, 3].::(1) = [1, 2, 3]</code>.
+ * @param x the element to append.
+ * @return the list with <code>x</code> appended at the beginning.
+ */
+ def ::(x: a): List[a] =
+ new scala.::[a](x, this);
+
+ /** Returns a list resulting from the concatenation of the given
+ * list <code>prefix</code> and this list.
+ * <p>
+ * Ex:<br>
+ * <code>[1, 2] ::: [3, 4] = [3, 4].:::([1, 2]) = [1, 2, 3, 4]</code>.
+ * @param prefix the list to concatenate at the beginning of this list.
+ * @return the concatenation of the two lists.
+ */
+ def :::(prefix: List[a]): List[a] =
+ if (prefix.isEmpty) this
+ else prefix.head :: (prefix.tail ::: this);
+
+ /** Returns the number of elements in the list.
+ * @return the number of elements in the list.
+ */
+ def length: Int = {
+ this match {
+ case Nil() => 0
+ case _ :: xs => xs.length + 1}
+ }
+
+ /** Returns the list without its last element.
+ * @return the list without its last element.
+ * @throws java.lang.RuntimeException if the list is empty.
+ */
+ def init: List[a] =
+ if (isEmpty) error("Nil.init")
+ else if (tail.isEmpty) Nil()
+ else head :: tail.init;
+
+ /** Returns the last element of this list.
+ * @return the last element of the list.
+ * @throws java.lang.RuntimeException if the list is empty.
+ */
+ def last: a =
+ if (isEmpty) error("Nil.last")
+ else if (tail.isEmpty) head
+ else tail.last;
+
+ /** Returns the <code>n</code> first elements of this list.
+ * @param n the number of elements to take.
+ * @return the <code>n</code> first elements of this list.
+ * @throws java.lang.RuntimeException if the list is too short.
+ */
+ def take(n: Int): List[a] =
+ if (n == 0) Nil()
+ else head :: tail.take(n-1);
+
+ /** Returns the list without its <code>n</code> first elements.
+ * @param n the number of elements to drop.
+ * @return the list without its <code>n</code> first elements.
+ * @throws java.lang.RuntimeException if the list is too short.
+ */
+ def drop(n: Int): List[a] =
+ if (n == 0) this
+ else tail.drop(n-1);
+
+ /** Returns the longest prefix of this list whose elements satisfy
+ * the predicate <code>p</code>.
+ * @param p the test predicate.
+ * @return the longest prefix of this list whose elements satisfy
+ * the predicate <code>p</code>.
+ */
+ def takeWhile(p: a => Boolean): List[a] =
+ if (isEmpty || !p(head)) Nil()
+ else head :: tail.takeWhile(p);
+
+ /** Returns the longest suffix of this list whose first element does not satisfy
+ * the predicate <code>p</code>.
+ * @param p the test predicate.
+ * @return the longest suffix of the list whose first element does not satisfy
+ * the predicate <code>p</code>.
+ */
+ def dropWhile(p: a => Boolean): List[a] =
+ if (isEmpty || !p(head)) this
+ else tail.dropWhile(p);
+
+ /** Returns the <code>n</code>-th element of this list. The first element
+ * (head of the list) is at position 0.
+ * @param n index of the element to return
+ * @return the element at position <code>n</code> in this list.
+ * @throws java.lang.RuntimeException if the list is too short.
+ */
+ def at(n: Int) = drop(n).head;
+
+ /** Returns the list resulting from applying the given function <code>f</code> to each
+ * element of this list.
+ * @param f function to apply to each element.
+ * @return <code>[f(a0), ..., f(an)]</code> if this list is <code>[a0, ..., an]</code>.
+ */
+ def map[b](f: a => b): List[b] =
+ if (isEmpty) Nil()
+ else f(head) :: tail.map(f);
+
+ /** Apply the given function <code>f</code> to each element of this list (while respecting
+ * the order of the elements).
+ * @param f the treatment to apply to each element.
+ */
+ def foreach(f: a => Unit): Unit =
+ if (isEmpty) {} else { f(head); tail.foreach(f) };
+
+ /** Returns all the elements of this list that satisfy the
+ * predicate <code>p</code>. The order of the elements is preserved.
+ * @param p the redicate used to filter the list.
+ * @return the elements of this list satisfying <code>p</code>.
+ */
+ def filter(p: a => Boolean): List[a] =
+ if (isEmpty) this
+ else if (p(head)) head :: tail.filter(p)
+ else tail.filter(p);
+
+ /** Tests if the predicate <code>p</code> is satisfied by all elements in this
+ * list.
+ * @param p the test predicate.
+ * @return True iff all elements of this list satisfy the predicate <code>p</code>.
+ */
+ def forall(p: a => Boolean): Boolean = isEmpty || (p(head) &&
+ tail.forall(p));
+
+ /** Tests the existence in this list of an element that satisfies the predicate
+ * <code>p</code>.
+ * @param p the test predicate.
+ * @return True iff there exists an element in this list that satisfies
+ * the predicate <code>p</code>.
+ */
+ def exists(p: a => Boolean): Boolean =
+ !isEmpty && (p(head) || tail.exists(p));
+
+ /** Combines the elements of this list together using the binary
+ * operator <code>op</code>, from left to right, and starting with
+ * the value <code>z</code>. Similar to <code>fold</code> but with
+ * a different order of the arguments, allowing to use nice constructions like
+ * <code>(z :_foldl l) { ... }</code>.
+ * @return <code>op(... (op(op(z,a0),a1) ...), an)</code> if the list
+ * is <code>[a0, a1, ..., an]</code>.
+ */
+ def :_foldl[b](z: b)(f: (b, a) => b): b = match {
+ case Nil() => z
+ case x :: xs => (xs.:_foldl@[b](f(z, x)))(f)
+ }
+
+ def foldr[b](z: b)(f: (a, b) => b): b = match {
+ case Nil() => z
+ case x :: xs => f(x, (xs foldr z)(f))
+ }
+
+ def foldl1(f: (a, a) => a): a = this match {
+ case Nil() => error("foldl1 of empty list")
+ case x :: xs => (x :_foldl xs)(f)
+ }
+
+ def foldr1(f: (a, a) => a): a = match {
+ case Nil() => error("foldr1 of empty list")
+ case x :: Nil() => x
+ case x :: xs => f(x, xs foldr1 f)
+ }
+
+ /** Applies the given function <code>f</code> to each element of this list, then concatenates
+ * the results.
+ * @param f the function to apply on each element.
+ * @return <code>f(a0) ::: ... ::: f(an)</code> if this list is
+ * <code>[a0, ..., an]</code>.
+ */
+ def flatMap[b](f: a => List[b]): List[b] =
+ if (isEmpty) Nil()
+ else f(head) ::: tail.flatMap(f);
+
+ /** Reverses the elements of this list.
+ * <p>
+ * Ex: <br>
+ * <code>[1, 2, 3] reverse = [3, 2, 1]</code>.
+ * @return the elements of this list in reverse order.
+ */
+ def reverse: List[a] = {
+ ((Nil(): List[a]) :_foldl this)((xs: List[a], x: a) => x :: xs)
+ }
+
+ /** Prints on standard output a raw textual representation of this list.
+ * <p>
+ * Ex: <br>
+ * <code>[1, 2, 3] print</code> will display <code>1 :: 2 :: 3 :: []</code>.
+ */
+ def print: Unit =
+ if (isEmpty) java.lang.System.out.println("Nil()")
+ else {
+ java.lang.System.out.print(head as java.lang.Object);
+ java.lang.System.out.print(" :: ");
+ tail.print
+ }
+ /*
+ def toArray: Array[a] = {
+ val xs = new Array[a](length);
+ copyToArray(xs, 0);
+ xs
+ }
+ */
+
+ /** Fills the given array <code>xs</code> with the elements of
+ * this list starting at position <code>start</code>. Does not
+ * work with empty lists.
+ * @param xs the array to fill.
+ * @param start starting index.
+ * @return the given array <code>xs</code> filled with this list.
+ * @throws error if the list is empty.
+ */
+ def copyToArray(xs: Array[a], start: Int): Int = {
+ xs(start) = head;
+ tail.copyToArray(xs, start + 1)
+ }
+
+ /** Returns a string representation of this list. The resulting string
+ * begins with the string <code>start</code> and is finished by the string
+ * <code>end</code>. Inside, the string representations of elements (w.r.t.
+ * the method <code>toString()</code>) are separated by the string
+ * <code>sep</code>.
+ * <p>
+ * Ex: <br>
+ * <code>[1, 2, 3].mkString("(", "; ", ")") = "(1; 2; 3)"</code>
+ * @param start starting string.
+ * @param sep separator string.
+ * @param end ending string.
+ * @return a string representation of this list.
+ */
+ def mkString(start: String, sep: String, end: String): String =
+ start +
+ (if (isEmpty) end
+ else if (tail.isEmpty) head.toString() + end
+ else head.toString().concat(sep).concat(tail.mkString("", sep, end)));
+
+ /** Return a list formed from this list and the specified list
+ * <code>that</code> by associating each element of the former with
+ * the element at the same position in the latter.
+ * @param that must have the same length as the self list.
+ * @return <code>[(a0,b0), ..., (an,bn)]</code> when
+ * <code>[a0, ..., an] zip [b0, ..., bn]</code> is invoked.
+ * @throws java.lang.RuntimeException if lists have different lengths.
+ */
+ def zip[b](that: List[b]): List[[a,b]] =
+ if (this.isEmpty || that.isEmpty) Nil()
+ else [this.head, that.head] :: this.tail.zip(that.tail);
+
+ /** Tests if the given value <code>elem</code> is a member of
+ * this list.
+ * @param elem element whose membership has to be tested.
+ * @return True iff there is an element of this list which is
+ * equal (w.r.t. <code>==</code>) to <code>elem</code>.
+ */
+ def contains(elem: a) = exists(
+ new Function1[a, Boolean] {
+ def apply(x: a): Boolean = x == elem;
+ });
+
+ /** Computes the union of this list and the given list
+ * <code>that</code>.
+ * @param that the list of elements to add to the list.
+ * @return a list without doubles containing the elements of this
+ * list and those of the given list <code>that</code>.
+ */
+ def union(that: List[a]): List[a] =
+ if (this.isEmpty) that
+ else {
+ val result = this.tail union that;
+ if (that contains this.head) result else this.head :: result;
+ }
+
+ /** Computes the difference between this list and the given list
+ * <code>that</code>.
+ * @param that the list of elements to remove from this list.
+ * @return this list without the elements of the given list <code>that</code>.
+ */
+ def diff(that: List[a]): List[a] =
+ if (that.isEmpty) this
+ else {
+ val result = this.tail diff that;
+ if (that contains this.head) result else this.head :: result;
+ }
+
+ /** Computes the intersection between this list and the given list
+ * <code>that</code>.
+ * @param that the list to intersect.
+ * @return the list of elements contained both in this list and
+ * in the given list <code>that</code>.
+ */
+ def intersect(that: List[a]): List[a] = filter(x => that contains x);
+
+ /** Removes redundant elements from the list. Uses the method <code>==</code>
+ * to decide if two elements are identical.
+ * @return the list without doubles.
+ */
+ def removeDuplicates: List[a] =
+ if (isEmpty) this
+ else {
+ val rest = tail.removeDuplicates;
+ if (rest contains head) rest else head :: rest
+ }
+ }
+}
+
+
diff --git a/sources/scala/Monitor.scala b/sources/scala/Monitor.scala
new file mode 100644
index 0000000000..cf7d6d4144
--- /dev/null
+++ b/sources/scala/Monitor.scala
@@ -0,0 +1,15 @@
+package scala with {
+
+ class Monitor extends NativeMonitor() with {
+
+ def synchronized[a](def p: a): a = {
+ var value: Ref[a] = null;
+ synchronised(=> value = Ref(p));
+ value.elem
+ }
+
+ def await(def cond: Boolean) = while (!cond) { this.wait() }
+
+ }
+
+}
diff --git a/sources/scala/Nil.scala b/sources/scala/Nil.scala
new file mode 100644
index 0000000000..508440b7e7
--- /dev/null
+++ b/sources/scala/Nil.scala
@@ -0,0 +1,13 @@
+package scala {
+
+ /* An empty list. Scala provides <code>[]</code> as syntactic sugar
+ * for <code>Nil</code>.
+ */
+ final case class Nil[c]() extends List[c] with {
+ def isEmpty = True;
+ def head: c = error("head of empty list");
+ def tail: List[c] = error("tail of empty list");
+ override def toString(): String = "[]";
+ }
+}
+
diff --git a/sources/scala/None.scala b/sources/scala/None.scala
new file mode 100644
index 0000000000..46dd9ce704
--- /dev/null
+++ b/sources/scala/None.scala
@@ -0,0 +1,6 @@
+package scala with {
+ final case class None[b] extends Option[b] with {
+ def isNone = True;
+ def get: b = error("None does not have an element.");
+ }
+} \ No newline at end of file
diff --git a/sources/scala/Option.scala b/sources/scala/Option.scala
new file mode 100644
index 0000000000..4e35740e48
--- /dev/null
+++ b/sources/scala/Option.scala
@@ -0,0 +1,21 @@
+package scala with {
+
+ abstract class Option[a] with {
+
+ abstract def isNone: Boolean;
+ abstract def get: a;
+
+ def map[b](f: (a)b): Option[b] = this match {
+ case None => this.as[Option[b]]
+ case Some(x) => Some(f(x))
+ }
+
+ def toList: List[a] = this match {
+ case None => []
+ case Some(x) => [x]
+ }
+
+ def print: Unit =
+ System.out.println(this.toString())
+ }
+} \ No newline at end of file
diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala
new file mode 100644
index 0000000000..f504813aab
--- /dev/null
+++ b/sources/scala/Predef.scala
@@ -0,0 +1,48 @@
+package scala {
+
+ module Predef {
+
+ val True = Boolean.True;
+ val False = Boolean.False;
+
+ def List[a](xs: Nil[a]): List[a] = [];
+ def List[a](xs: [a]): List[a] = xs._1 :: [];
+ def List[a](xs: [a, a]): List[a] = xs._1 :: xs._2 :: [];
+ def List[a](xs: [a, a, a]): List[a] = xs._1 :: xs._2 :: xs._3 :: [];
+ def List[a](xs: [a, a, a, a]): List[a] = xs._1 :: xs._2 :: xs._3 :: xs._4 :: [];
+ def List[a](xs: [a, a, a, a, a]): List[a] = xs._1 :: xs._2 :: xs._3 :: xs._4 :: xs._5 :: [];
+ def List[a](xs: [a, a, a, a, a, a]): List[a] = xs._1 :: xs._2 :: xs._3 :: xs._4 :: xs._5 :: xs._6 :: [];
+ def List[a](xs: [a, a, a, a, a, a, a]): List[a] = xs._1 :: xs._2 :: xs._3 :: xs._4 :: xs._5 :: xs._6 :: xs._7 :: [];
+ def List[a](xs: [a, a, a, a, a, a, a, a]): List[a] = xs._1 :: xs._2 :: xs._3 :: xs._4 :: xs._5 :: xs._6 :: xs._7 :: xs._8 :: [];
+ def List[a](xs: [a, a, a, a, a, a, a, a, a]): List[a] = xs._1 :: xs._2 :: xs._3 :: xs._4 :: xs._5 :: xs._6 :: xs._7 :: xs._8 :: xs._9 :: [];
+
+ def error[a](x: String):a = (new java.lang.RuntimeException(x)).throw;
+
+ def ConsStream[a](hd: a, def tl: Stream[a]): Stream[a] =
+ new ConsStreamClass(hd, () => tl);
+
+ def range(lo: Int, hi: Int): List[Int] =
+ if (lo > hi) [] else lo :: range(lo + 1, hi);
+
+ def while(def condition: Boolean)(def command: Unit): Unit =
+ if (condition) {
+ command; while(condition)(command)
+ } else {
+ }
+
+ trait Until {
+ def until(def condition: Boolean): Unit
+ }
+
+ def repeat(def command: Unit): Until =
+ new Until {
+ def until(def condition: Boolean): Unit = {
+ command ;
+ if (condition) {}
+ else until(condition)
+ }
+ }
+ }
+}
+
+
diff --git a/sources/scala/Some.scala b/sources/scala/Some.scala
new file mode 100644
index 0000000000..5957846a5f
--- /dev/null
+++ b/sources/scala/Some.scala
@@ -0,0 +1,6 @@
+package scala with {
+ final case class Some[c](x: c) extends Option[c] with {
+ def isNone = False;
+ def get: c = x;
+ }
+} \ No newline at end of file
diff --git a/sources/scala/Stream.scala b/sources/scala/Stream.scala
new file mode 100644
index 0000000000..fe6cd98130
--- /dev/null
+++ b/sources/scala/Stream.scala
@@ -0,0 +1,117 @@
+package scala;
+
+trait Stream[a] {
+
+ def isEmpty: Boolean;
+ def head: a;
+ def tail: Stream[a];
+
+ protected def error[a](x: String):a = (new java.lang.RuntimeException(x)).throw;
+
+ def length: Int = if (isEmpty) 0 else tail.length + 1;
+
+ def append(def rest: Stream[a]): Stream[a] =
+ if (isEmpty) rest
+ else ConsStream(head, tail.append(rest));
+
+ def init: Stream[a] =
+ if (isEmpty) error("EmptyStream.init")
+ else if (tail.isEmpty) new EmptyStream[a]()
+ else ConsStream(head, tail.init);
+
+ def last: a =
+ if (isEmpty) error("EmptyStream.last")
+ else if (tail.isEmpty) head
+ else tail.last;
+
+ def takeWhile(p: a => Boolean): Stream[a] =
+ if (isEmpty || !p(head)) new EmptyStream[a]()
+ else ConsStream(head, tail.takeWhile(p));
+
+ def dropWhile(p: a => Boolean): Stream[a] =
+ if (isEmpty || !p(head)) this
+ else tail.dropWhile(p);
+
+ def take(n: Int): Stream[a] =
+ if (n == 0) new EmptyStream[a]()
+ else ConsStream(head, tail.take(n-1));
+
+ def drop(n: Int): Stream[a] =
+ if (n == 0) this
+ else tail.drop(n-1);
+
+ def at(n: Int) = drop(n).head;
+
+ def map[b](f: a => b): Stream[b] =
+ if (isEmpty) new EmptyStream[b]()
+ else ConsStream(f(head), tail.map(f));
+
+ def foreach(f: a => Unit): Unit =
+ if (isEmpty) {}
+ else { f(head); tail.foreach(f) }
+
+ def filter(p: a => Boolean): Stream[a] =
+ if (isEmpty) this
+ else if (p(head)) ConsStream(head, tail.filter(p))
+ else tail.filter(p);
+
+ def forall(p: a => Boolean): Boolean =
+ isEmpty || (p(head) && tail.forall(p));
+
+ def exists(p: a => Boolean): Boolean =
+ !isEmpty && (p(head) || tail.exists(p));
+
+ // the next four functions are obsolete!
+
+ def reduce(op: (a, a) => a): a =
+ if (isEmpty) error("reduce of empty stream")
+ else tail.fold(op)(head);
+
+ def reduceRight(op: (a, a) => a): a =
+ if (isEmpty) error("reduce of empty stream")
+ else if (tail.isEmpty) head
+ else op(head, tail.reduceRight(op));
+
+ def fold[b](op: (b, a) => b)(z: b): b =
+ if (isEmpty) z
+ else tail.fold(op)(op(z, head));
+
+ def foldRight[b](op: (a, b) => b)(z: b): b =
+ if (isEmpty) z
+ else op(head, tail.foldRight(op)(z));
+
+ def flatMap[b](f: a => Stream[b]): Stream[b] =
+ if (isEmpty) new EmptyStream[b]()
+ else f(head).append(tail.flatMap(f));
+
+ def reverse: Stream[a] = {
+ def snoc(xs: Stream[a], x: a): Stream[a] = ConsStream(x, xs);
+ fold(snoc)(new EmptyStream[a]())
+ }
+
+ // The following method is not compilable without run-time type
+ // information. It should therefore be left commented-out for
+ // now.
+ // def toArray: Array[a] = {
+ // val xs = new Array[a](length);
+ // copyToArray(xs, 0);
+ // xs
+ // }
+
+ def copyToArray(xs: Array[a], start: Int): Int = {
+ xs(start) = head;
+ tail.copyToArray(xs, start + 1)
+ }
+
+ def zip[b](that: Stream[b]): Stream[[a, b]] =
+ if (this.isEmpty || that.isEmpty) new EmptyStream[[a, b]]()
+ else ConsStream([this.head, that.head], this.tail.zip(that.tail));
+
+ def print: Unit =
+ if (isEmpty) System.out.println("EmptyStream")
+ else {
+ System.out.print(head as java.lang.Object);
+ System.out.print(", ");
+ tail.print
+ }
+}
diff --git a/sources/scala/Tuple1.scala b/sources/scala/Tuple1.scala
new file mode 100644
index 0000000000..d0cc8cdda5
--- /dev/null
+++ b/sources/scala/Tuple1.scala
@@ -0,0 +1,24 @@
+// DO NOT EDIT. Automatically generated file!
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala {
+ case class Tuple1[T1](_1: T1) extends scala.Object with {
+
+ override def hashCode() = _1.hashCode();
+
+ override def == (other: Any) =
+ if (other is Tuple1[T1]) {
+ val that = other as Tuple1[T1];
+ (_1 == that._1)
+ } else Boolean.False;
+
+ override def toString() = "[" + _1 + "]";
+ }
+}
diff --git a/sources/scala/Tuple2.scala b/sources/scala/Tuple2.scala
new file mode 100644
index 0000000000..a07a0e6ca2
--- /dev/null
+++ b/sources/scala/Tuple2.scala
@@ -0,0 +1,24 @@
+// DO NOT EDIT. Automatically generated file!
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala {
+ case class Tuple2[T1, T2](_1: T1, _2: T2) extends scala.Object with {
+
+ override def hashCode() = _1.hashCode() ^ _2.hashCode();
+
+ override def == (other: Any) =
+ if (other is Tuple2[T1, T2]) {
+ val that = other as Tuple2[T1, T2];
+ (_1 == that._1) && (_2 == that._2)
+ } else Boolean.False;
+
+ override def toString() = "(" + _1 + "," + _2 + ")";
+ }
+}
diff --git a/sources/scala/Tuple3.scala b/sources/scala/Tuple3.scala
new file mode 100644
index 0000000000..24320546e9
--- /dev/null
+++ b/sources/scala/Tuple3.scala
@@ -0,0 +1,24 @@
+// DO NOT EDIT. Automatically generated file!
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala {
+ case class Tuple3[T1, T2, T3](_1: T1, _2: T2, _3: T3) extends scala.Object with {
+
+ override def hashCode() = _1.hashCode() ^ _2.hashCode() ^ _3.hashCode();
+
+ override def == (other: Any) =
+ if (other is Tuple3[T1, T2, T3]) {
+ val that = other as Tuple3[T1, T2, T3];
+ (_1 == that._1) && (_2 == that._2) && (_3 == that._3)
+ } else Boolean.False;
+
+ override def toString() = "(" + _1 + "," + _2 + "," + _3 + ")";
+ }
+}
diff --git a/sources/scala/Tuple4.scala b/sources/scala/Tuple4.scala
new file mode 100644
index 0000000000..2238f726bc
--- /dev/null
+++ b/sources/scala/Tuple4.scala
@@ -0,0 +1,24 @@
+// DO NOT EDIT. Automatically generated file!
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala {
+ case class Tuple4[T1, T2, T3, T4](_1: T1, _2: T2, _3: T3, _4: T4) extends scala.Object with {
+
+ override def hashCode() = _1.hashCode() ^ _2.hashCode() ^ _3.hashCode() ^ _4.hashCode();
+
+ override def == (other: Any) =
+ if (other is Tuple4[T1, T2, T3, T4]) {
+ val that = other as Tuple4[T1, T2, T3, T4];
+ (_1 == that._1) && (_2 == that._2) && (_3 == that._3) && (_4 == that._4)
+ } else Boolean.False;
+
+ override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + ")";
+ }
+}
diff --git a/sources/scala/Tuple5.scala b/sources/scala/Tuple5.scala
new file mode 100644
index 0000000000..1bc9c8dfc2
--- /dev/null
+++ b/sources/scala/Tuple5.scala
@@ -0,0 +1,24 @@
+// DO NOT EDIT. Automatically generated file!
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala {
+ case class Tuple5[T1, T2, T3, T4, T5](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5) extends scala.Object with {
+
+ override def hashCode() = _1.hashCode() ^ _2.hashCode() ^ _3.hashCode() ^ _4.hashCode() ^ _5.hashCode();
+
+ override def == (other: Any) =
+ if (other is Tuple5[T1, T2, T3, T4, T5]) {
+ val that = other as Tuple5[T1, T2, T3, T4, T5];
+ (_1 == that._1) && (_2 == that._2) && (_3 == that._3) && (_4 == that._4) && (_5 == that._5)
+ } else Boolean.False;
+
+ override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + ")";
+ }
+}
diff --git a/sources/scala/Tuple6.scala b/sources/scala/Tuple6.scala
new file mode 100644
index 0000000000..52cf40961c
--- /dev/null
+++ b/sources/scala/Tuple6.scala
@@ -0,0 +1,24 @@
+// DO NOT EDIT. Automatically generated file!
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala {
+ case class Tuple6[T1, T2, T3, T4, T5, T6](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6) extends scala.Object with {
+
+ override def hashCode() = _1.hashCode() ^ _2.hashCode() ^ _3.hashCode() ^ _4.hashCode() ^ _5.hashCode() ^ _6.hashCode();
+
+ override def == (other: Any) =
+ if (other is Tuple6[T1, T2, T3, T4, T5, T6]) {
+ val that = other as Tuple6[T1, T2, T3, T4, T5, T6];
+ (_1 == that._1) && (_2 == that._2) && (_3 == that._3) && (_4 == that._4) && (_5 == that._5) && (_6 == that._6)
+ } else Boolean.False;
+
+ override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + ")";
+ }
+}
diff --git a/sources/scala/Tuple7.scala b/sources/scala/Tuple7.scala
new file mode 100644
index 0000000000..ea45d666dd
--- /dev/null
+++ b/sources/scala/Tuple7.scala
@@ -0,0 +1,24 @@
+// DO NOT EDIT. Automatically generated file!
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala {
+ case class Tuple7[T1, T2, T3, T4, T5, T6, T7](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7) extends scala.Object with {
+
+ override def hashCode() = _1.hashCode() ^ _2.hashCode() ^ _3.hashCode() ^ _4.hashCode() ^ _5.hashCode() ^ _6.hashCode() ^ _7.hashCode();
+
+ override def == (other: Any) =
+ if (other is Tuple7[T1, T2, T3, T4, T5, T6, T7]) {
+ val that = other as Tuple7[T1, T2, T3, T4, T5, T6, T7];
+ (_1 == that._1) && (_2 == that._2) && (_3 == that._3) && (_4 == that._4) && (_5 == that._5) && (_6 == that._6) && (_7 == that._7)
+ } else Boolean.False;
+
+ override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + ")";
+ }
+}
diff --git a/sources/scala/Tuple8.scala b/sources/scala/Tuple8.scala
new file mode 100644
index 0000000000..8e3581da1d
--- /dev/null
+++ b/sources/scala/Tuple8.scala
@@ -0,0 +1,24 @@
+// DO NOT EDIT. Automatically generated file!
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala {
+ case class Tuple8[T1, T2, T3, T4, T5, T6, T7, T8](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8) extends scala.Object with {
+
+ override def hashCode() = _1.hashCode() ^ _2.hashCode() ^ _3.hashCode() ^ _4.hashCode() ^ _5.hashCode() ^ _6.hashCode() ^ _7.hashCode() ^ _8.hashCode();
+
+ override def == (other: Any) =
+ if (other is Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) {
+ val that = other as Tuple8[T1, T2, T3, T4, T5, T6, T7, T8];
+ (_1 == that._1) && (_2 == that._2) && (_3 == that._3) && (_4 == that._4) && (_5 == that._5) && (_6 == that._6) && (_7 == that._7) && (_8 == that._8)
+ } else Boolean.False;
+
+ override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + ")";
+ }
+}
diff --git a/sources/scala/Tuple9.scala b/sources/scala/Tuple9.scala
new file mode 100644
index 0000000000..3bf04f158b
--- /dev/null
+++ b/sources/scala/Tuple9.scala
@@ -0,0 +1,24 @@
+// DO NOT EDIT. Automatically generated file!
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala {
+ case class Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5, _6: T6, _7: T7, _8: T8, _9: T9) extends scala.Object with {
+
+ override def hashCode() = _1.hashCode() ^ _2.hashCode() ^ _3.hashCode() ^ _4.hashCode() ^ _5.hashCode() ^ _6.hashCode() ^ _7.hashCode() ^ _8.hashCode() ^ _9.hashCode();
+
+ override def == (other: Any) =
+ if (other is Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) {
+ val that = other as Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9];
+ (_1 == that._1) && (_2 == that._2) && (_3 == that._3) && (_4 == that._4) && (_5 == that._5) && (_6 == that._6) && (_7 == that._7) && (_8 == that._8) && (_9 == that._9)
+ } else Boolean.False;
+
+ override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + ")";
+ }
+}