summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSean McDirmid <sean.mcdirmid@gmail.com>2007-07-18 07:40:06 +0000
committerSean McDirmid <sean.mcdirmid@gmail.com>2007-07-18 07:40:06 +0000
commit02189a8d5b0e29da3ad5ebb6dfc4ac8bd028c70d (patch)
tree68535b73d6861265198771fb503593bc75d2de83 /src
parentc5c6d4a8ce75993d2dcd80f6360b45de534a3f41 (diff)
downloadscala-02189a8d5b0e29da3ad5ebb6dfc4ac8bd028c70d.tar.gz
scala-02189a8d5b0e29da3ad5ebb6dfc4ac8bd028c70d.tar.bz2
scala-02189a8d5b0e29da3ad5ebb6dfc4ac8bd028c70d.zip
Updated Stream to be the projection of List.
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/Array.scala4
-rw-r--r--src/library/scala/Iterable.scala32
-rw-r--r--src/library/scala/IterableProxy.scala2
-rw-r--r--src/library/scala/Iterator.scala13
-rw-r--r--src/library/scala/List.scala18
-rw-r--r--src/library/scala/Predef.scala2
-rw-r--r--src/library/scala/RandomAccessSeq.scala102
-rw-r--r--src/library/scala/Seq.scala95
-rw-r--r--src/library/scala/Stream.scala33
-rw-r--r--src/library/scala/collection/mutable/Buffer.scala7
-rw-r--r--src/library/scala/runtime/RichString.scala5
-rw-r--r--src/library/scala/runtime/RichStringBuilder.scala10
12 files changed, 234 insertions, 89 deletions
diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala
index 871fa97b0d..aaf72f1c92 100644
--- a/src/library/scala/Array.scala
+++ b/src/library/scala/Array.scala
@@ -187,7 +187,7 @@ object Array {
* @author Martin Odersky
* @version 1.0
*/
-final class Array[A](_length: Int) extends RandomAccessSeq[A] {
+final class Array[A](_length: Int) extends RandomAccessSeq.Mutable[A] {
/** The length of the array */
def length: Int = throw new Error()
@@ -225,7 +225,7 @@ final class Array[A](_length: Int) extends RandomAccessSeq[A] {
* @throws ArrayIndexOutOfBoundsException if <code>i < 0</code> or
* <code>length <= i</code>
*/
- def update(i: Int, x: A): Unit = throw new Error()
+ override def update(i: Int, x: A): Unit = throw new Error()
/** An iterator returning the elements of this array, starting from 0.
*/
diff --git a/src/library/scala/Iterable.scala b/src/library/scala/Iterable.scala
index fb96ec5d40..0acd9b824d 100644
--- a/src/library/scala/Iterable.scala
+++ b/src/library/scala/Iterable.scala
@@ -74,6 +74,9 @@ object Iterable {
*/
trait Projection[+A] extends Iterable[A] {
override def projection = this
+ /** convert to a copied strict collection */
+ def force : Iterable[A] = toList
+
/** non-strict */
override def filter(p : A => Boolean) : Projection[A] = new Projection[A] {
def elements = Projection.this.elements.filter(p)
@@ -86,6 +89,16 @@ object Iterable {
override def flatMap[B](f: A => Iterable[B]) : Projection[B] = new Projection[B] {
def elements = Projection.this.elements.flatMap(a => f(a).elements)
}
+ /** non-strict */
+ override def takeWhile(p: A => Boolean): Projection[A] = new Projection[A] {
+ def elements = Projection.this.elements.takeWhile(p)
+ }
+ /** The projection resulting from the concatenation of this projection with the <code>rest</code> projection.
+ * @param rest The projection that gets appended to this projection
+ */
+ def append[B >: A](rest : => Iterable[B]): Projection[B] = new Projection[B] {
+ def elements = Projection.this.elements ++ rest.elements
+ }
}
}
@@ -182,7 +195,7 @@ trait Iterable[+A] {
* @return the longest prefix of this iterable whose elements satisfy
* the predicate <code>p</code>.
*/
- def takeWhile(p: A => Boolean): Collection[A] =
+ def takeWhile(p: A => Boolean): Iterable[A] =
(new ArrayBuffer[A] ++ elements.takeWhile(p))
/** Returns the longest suffix of this iterable whose first element
@@ -200,7 +213,7 @@ trait Iterable[+A] {
* elements of this iterable, or else the whole iterable, if it has less
* than <code>n</code> elements.
*
- * @deprecated API doesn't make sense for non-ordered collections
+ * @deprecated API does not make sense for non-ordered collections
* @param n the number of elements to take
* @return the new iterable
*/
@@ -212,7 +225,7 @@ trait Iterable[+A] {
* iterable is returned.
*
* @note Will not terminate for infinite-sized collections.
- * @deprecated API doesn't make sense for non-ordered collections
+ * @deprecated API does not make sense for non-ordered collections
* @param n the number of elements to drop
* @return the new iterable
*/
@@ -250,7 +263,7 @@ trait Iterable[+A] {
/** Find and return the first element of the iterable object satisfying a
* predicate, if any.
*
- * @note Will not terminate for infinite-sized collections.
+ * @note may not terminate for infinite-sized collections.
* @param p the predicate
* @return the first element in the iterable object satisfying <code>p</code>,
* or <code>None</code> if none exists.
@@ -259,7 +272,7 @@ trait Iterable[+A] {
/** Returns index of the first element satisying a predicate, or -1.
*
- * @note Will not terminate for infinite-sized collections.
+ * @note may not terminate for infinite-sized collections.
* @param p the predicate
* @return the index of the first element satisfying <code>p</code>,
* or -1 if such an element does not exist
@@ -278,7 +291,7 @@ trait Iterable[+A] {
/** Returns the index of the first occurence of the specified
* object in this iterable object.
*
- * @note May not terminate for infinite-sized collections.
+ * @note may not terminate for infinite-sized collections.
* @param elem element to search for.
* @return the index in this sequence of the first occurence of the
* specified element, or -1 if the sequence does not contain
@@ -365,7 +378,7 @@ trait Iterable[+A] {
/** Checks if the other iterable object contains the same elements.
*
- * @note Will not terminate for infinite-sized collections.
+ * @note will not terminate for infinite-sized collections.
* @param that the other iterable object
* @return true, iff both iterable objects contain the same elements.
*/
@@ -387,6 +400,7 @@ trait Iterable[+A] {
/**
* Create a stream which contains all the elements of this iterable object.
+ * @note consider using <code>projection</code> for lazy behavior.
*/
def toStream: Stream[A] = Stream.fromIterator(elements)
@@ -469,13 +483,13 @@ trait Iterable[+A] {
*/
def projection : Iterable.Projection[A] = new Iterable.Projection[A] {
def elements = Iterable.this.elements
+ override def force = Iterable.this
}
/** returns true iff this collection has a bound size.
- * Only true if this iterable is a <code>Collection</code>.
* Many APIs in this trait will not work on collections of
* unbound sizes.
*/
- final def hasDefiniteSize = this.isInstanceOf[Collection[Nothing]]
+ def hasDefiniteSize = true
}
diff --git a/src/library/scala/IterableProxy.scala b/src/library/scala/IterableProxy.scala
index 757f50ae7a..a66b110f24 100644
--- a/src/library/scala/IterableProxy.scala
+++ b/src/library/scala/IterableProxy.scala
@@ -31,7 +31,7 @@ trait IterableProxy[+A] extends Iterable[A] with Proxy {
override def map[B](f: A => B): Iterable[B] = self map f
override def flatMap[B](f: A => Iterable[B]): Iterable[B] = self flatMap f
override def filter(p: A => Boolean): Iterable[A] = self filter p
- override def takeWhile(p: A => Boolean): Collection[A] = self takeWhile p
+ override def takeWhile(p: A => Boolean): Iterable[A] = self takeWhile p
override def dropWhile(p: A => Boolean): Collection[A] = self dropWhile p
@deprecated override def take(n: Int): Collection[A] = self take n
@deprecated override def drop(n: Int): Collection[A] = self drop n
diff --git a/src/library/scala/Iterator.scala b/src/library/scala/Iterator.scala
index d65abe2ef3..f81b94939f 100644
--- a/src/library/scala/Iterator.scala
+++ b/src/library/scala/Iterator.scala
@@ -245,9 +245,16 @@ trait Iterator[+A] {
/** Returns a new iterator that first yields the elements of this
* iterator followed by the elements provided by iterator <code>that</code>.
*/
- def ++[B >: A](that: Iterator[B]) = new Iterator[B] {
- def hasNext = Iterator.this.hasNext || that.hasNext
- def next() = if (Iterator.this.hasNext) Iterator.this.next else that.next
+ def ++[B >: A](that: => Iterator[B]) = new Iterator[B] {
+ // optimize a little bit to prevent n log n behavior.
+ var what : Iterator[B] = Iterator.this
+ def hasNext = if (what.hasNext) true
+ else if (what eq Iterator.this) {
+ what = that
+ what.hasNext
+ } else false
+
+ def next = { hasNext; what.next }
}
/** Applies the given function <code>f</code> to each element of
diff --git a/src/library/scala/List.scala b/src/library/scala/List.scala
index 787d37727f..c39051145c 100644
--- a/src/library/scala/List.scala
+++ b/src/library/scala/List.scala
@@ -1160,6 +1160,24 @@ sealed abstract class List[+A] extends Seq[A] {
}
override protected def stringPrefix = "List"
+ override def projection = toStream
+ override def toStream : Stream[A] = new Stream.Definite[A] {
+ override def force : List[A] = List.this
+ override def isEmpty = List.this.isEmpty
+ override def head = List.this.head
+ override def tail = List.this.tail.toStream
+ protected def addDefinedElems(buf: StringBuilder, prefix: String): StringBuilder = if (!isEmpty) {
+ var prefix0 = prefix
+ var buf1 = buf.append(prefix0).append(head)
+ prefix0 = ", "
+ var tail0 = tail
+ while (!tail0.isEmpty) {
+ buf1 = buf.append(prefix0).append(tail0.head)
+ tail0 = tail0.tail
+ }
+ buf1
+ } else buf
+ }
}
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index 947f141111..2372d4ea92 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -35,7 +35,9 @@ object Predef {
type boolean = scala.Boolean
type unit = scala.Unit
+ /** @deprecated use <code>Nothing</code> instead */
@deprecated type All = Nothing
+ /** @deprecated use <code>Null</code> instead */
@deprecated type AllRef = Null
/** @deprecated use <code>Int</code> instead */
@deprecated type Integer = java.lang.Integer
diff --git a/src/library/scala/RandomAccessSeq.scala b/src/library/scala/RandomAccessSeq.scala
index 7270d42074..edee52b250 100644
--- a/src/library/scala/RandomAccessSeq.scala
+++ b/src/library/scala/RandomAccessSeq.scala
@@ -3,14 +3,45 @@ package scala
object RandomAccessSeq {
trait Projection[+A] extends Seq.Projection[A] with RandomAccessSeq[A] {
override def projection = this
+ override def force : RandomAccessSeq[A] = toArray
protected class MapProjection[B](f : A => B) extends super.MapProjection(f) with Projection[B]
override def map[B](f: A => B) : Projection[B] = new MapProjection[B](f)
-
+ override def append[B >: A](that: => Iterable[B]): Projection[B] = {
+ val that0 : Seq[B] = that match {
+ case that : Seq.Projection[b] => that
+ case that : Seq[b] => that
+ case that => that.toList
+ }
+ new Projection[B] {
+ def length = Projection.this.length + that0.length
+ def apply(idx : Int) =
+ if (idx < Projection.this.length) Projection.this(idx)
+ else that0(idx - Projection.this.length)
+ }
+ }
}
/** A random access sequence that supports update (e.g., an array) */
trait Mutable[A] extends RandomAccessSeq[A] {
+ /** <p>
+ * Update the element at given index.
+ * </p>
+ * <p>
+ * Indices start a <code>0</code>; <code>xs.apply(0)</code> is the first
+ * element of mutable sequence <code>xs</code>.
+ * </p>
+ * <p>
+ * Note the indexing syntax <code>xs(i) = x</code> is a shorthand
+ * for <code>xs.update(i, x)</code>.
+ * </p>
+ *
+ * @param i the index
+ * @param x the value to be written at index <code>i</code>
+ * @throws ArrayIndexOutOfBoundsException if <code>i < 0</code> or
+ * <code>length <= i</code>
+ */
def update(idx : Int, what : A) : Unit
override def projection : MutableProjection[A] = new MutableProjection[A] {
+ override def force : Mutable[A] = Mutable.this
def update(idx : Int, what : A) : Unit = Mutable.this.update(idx, what)
def length = Mutable.this.length
def apply(idx : Int) = Mutable.this.apply(idx)
@@ -20,16 +51,35 @@ object RandomAccessSeq {
def apply(idx : Int) = Mutable.this.apply(idx)
override def stringPrefix = Mutable.this.stringPrefix + "RO"
}
+ override def drop( from: Int): Mutable[A] = slice(from, length)
+ override def take(until: Int): Mutable[A] = slice(0, until)
+ override def slice(from : Int, until : Int) : Mutable[A] = {
+ if (from == 0 && until >= length) return projection
+ else if (from >= until) new MutableProjection[A] {
+ def length = 0
+ def apply(idx : Int) = throw new Predef.IndexOutOfBoundsException
+ def update(idx : Int, what : A) = throw new Predef.IndexOutOfBoundsException
+ } else new MutableProjection[A] {
+ def length = until - from
+ def apply(idx : Int) = if (idx < 0 || idx >= length) throw new Predef.IndexOutOfBoundsException
+ else Mutable.this.apply(from + idx)
+ def update(idx : Int, what : A) =
+ if (idx < 0 || idx >= length) throw new Predef.IndexOutOfBoundsException
+ else Mutable.this.update(from + idx, what)
+ }
+ }
+ override def reverse : Mutable[A] = new MutableProjection[A] {
+ def update(idx : Int, what : A) : Unit = Mutable.this.update(length - idx - 1, what)
+ def length = Mutable.this.length
+ def apply(idx : Int) = Mutable.this.apply(length - idx - 1)
+ override def stringPrefix = Mutable.this.stringPrefix + "R"
+ override def reverse : MutableProjection[A] = Mutable.this.projection
+ }
}
trait MutableProjection[A] extends Projection[A] with Mutable[A] {
+ // XXX: must copy.
+ override def force : Mutable[A] = toArray
override def projection : MutableProjection[A] = this
- override def reverse : MutableProjection[A] = new MutableProjection[A] {
- def update(idx : Int, what : A) : Unit = MutableProjection.this.update(length - idx - 1, what)
- def length = MutableProjection.this.length
- def apply(idx : Int) = MutableProjection.this.apply(length - idx - 1)
- override def stringPrefix = MutableProjection.this.stringPrefix + "R"
- override def reverse : MutableProjection[A] = MutableProjection.this
- }
}
}
@@ -57,13 +107,6 @@ trait RandomAccessSeq[+A] extends Seq[A] {
ret
}
}
- /** Appends two random access sequences in a non-strict way */
- def +++[B >: A](that: RandomAccessSeq[B]): RandomAccessSeq.Projection[B] = new RandomAccessSeq.Projection[B] {
- def length = RandomAccessSeq.this.length + that.length
- def apply(idx : Int) =
- if (idx < RandomAccessSeq.this.length) RandomAccessSeq.this(idx)
- else that(idx - RandomAccessSeq.this.length)
- }
override def drop( from: Int): RandomAccessSeq[A] = slice(from, length)
override def take(until: Int): RandomAccessSeq[A] = slice(0, until)
override def slice(from : Int, until : Int) : RandomAccessSeq[A] = {
@@ -77,13 +120,40 @@ trait RandomAccessSeq[+A] extends Seq[A] {
else RandomAccessSeq.this.apply(from + idx)
}
}
-
override def reverse : Seq[A] = new RandomAccessSeq.Projection[A] {
def length = RandomAccessSeq.this.length
def apply(idx : Int) = RandomAccessSeq.this.apply(length - idx - 1)
override def stringPrefix = RandomAccessSeq.this.stringPrefix + "R"
override def reverse : RandomAccessSeq.Projection[A] = RandomAccessSeq.this.projection
}
+ override def ++[B >: A](that : Iterable[B]) : RandomAccessSeq[B] = that match {
+ case that : RandomAccessSeq[b] =>
+ val ret = new Array[B](length + that.length)
+ copyToArray(ret, 0)
+ (that : RandomAccessSeq[B]).copyToArray(ret, length)
+ ret
+ case that =>
+ val buf = new scala.collection.mutable.ArrayBuffer[B]
+ this copyToBuffer buf
+ that copyToBuffer buf
+ buf.readOnly
+ }
+
+ override def toStream : Stream[A] = new Stream.Definite[A] {
+ override def isEmpty = RandomAccessSeq.this.isEmpty
+ override def head = RandomAccessSeq.this.apply(0)
+ override def tail = RandomAccessSeq.this.drop(1).toStream
+ protected def addDefinedElems(buf: compat.StringBuilder, prefix: String): compat.StringBuilder = {
+ var prefix0 = prefix
+ var buf0 =buf
+ elements.foreach{e =>
+ buf0 = buf0.append(prefix0).append(e)
+ prefix0 = ", "
+ }
+ buf0
+ }
+ }
+
/** will return false if index is out of bounds */
final def safeIs(idx : Int, a : Any) = if (idx >= 0 && idx < length) this(idx) == a else false
diff --git a/src/library/scala/Seq.scala b/src/library/scala/Seq.scala
index 606cc351f8..a076cbf2ef 100644
--- a/src/library/scala/Seq.scala
+++ b/src/library/scala/Seq.scala
@@ -64,6 +64,8 @@ object Seq {
*/
trait Projection[+A] extends Seq[A] with Iterable.Projection[A] {
override def projection = this
+ override def force : Seq[A] = toList
+
override def map[B](f: A => B) : Projection[B] = new MapProjection(f)
protected class MapProjection[B](f : A => B) extends Projection[B] {
def length = Projection.this.length
@@ -95,7 +97,46 @@ object Seq {
throw new IndexOutOfBoundsException
}
}
- override def filter(p : A => Boolean) : Projection[A] = new Filter(p)
+ override def append[B >: A](that: => Iterable[B]) : Projection[B] = that match {
+ case that : Seq[b] => new Projection[B] {
+ def length = Projection.this.length + that.length
+ def elements : Iterator[B] = Projection.this.elements ++ (that.elements:Iterator[B])
+ def apply(idx : Int) =
+ if (idx < Projection.this.length) Projection.this(idx)
+ else that(idx - Projection.this.length)
+ }
+ case that => (this ++ that).projection // sucks but no other option.
+ }
+
+ protected abstract class ComputeSize[B] extends Projection[B] {
+ def apply(idx : Int) : B = {
+ var sz = 0
+ val i = elements
+ while (i.hasNext) {
+ val ret = i.next
+ if (sz == idx) return ret
+ sz += 1
+ }
+ throw new Predef.IndexOutOfBoundsException
+ }
+ override def length = {
+ val i = elements
+ var sz = 0
+ while (i.hasNext) {
+ sz += 1
+ i.next
+ }
+ sz
+ }
+ }
+ override def takeWhile(p: A => Boolean): Projection[A] = new ComputeSize[A] {
+ override def stringPrefix = Projection.this.stringPrefix + "TW"
+ override def elements = Projection.this.elements.takeWhile(p)
+ }
+ override def filter(p : A => Boolean) : Projection[A] = new ComputeSize[A] {
+ override def stringPrefix = Projection.this.stringPrefix + "F"
+ override def elements = Projection.this.elements.filter(p)
+ }
}
}
@@ -151,6 +192,9 @@ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Collection[A] {
case 0 => None
case n => Some(this(n-1))
}
+ /** Returns as an option the first element of this list or None if list is empty.
+ *
+ */
def headOption : Option[A] = if (isEmpty) None else Some(apply(0))
@@ -245,18 +289,6 @@ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Collection[A] {
result.toList
}
- /*
- new Seq.Projection[A] {
- def length = {
- val sz = Seq.this.length
- if (n <= sz) n else sz
- }
- def apply(idx : Int) =
- if (idx >= n) throw new Predef.IndexOutOfBoundsException
- else (Seq.this.apply(n))
- override def stringPrefix = Seq.this.stringPrefix + "T" + n
- }
- */
/** Returns this sequence without its <code>n</code> first elements
* If this sequence has less than <code>n</code> elements, the empty
@@ -266,8 +298,9 @@ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Collection[A] {
* @return the new sequence
*/
override def drop(n: Int): Seq[A] = {
+ import scala.collection.mutable.ListBuffer
var m = 0
- val result = new scala.collection.mutable.ListBuffer[A]
+ val result = new ListBuffer[A]
val i = elements
while (m < n && i.hasNext) {
i.next; m = m + 1
@@ -286,15 +319,6 @@ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Collection[A] {
*/
def slice(from : Int, until : Int) : Seq[A] = drop(from).take(until - from)
- /*new Seq.Projection[A] {
- def length = {
- val sz = Seq.this.length
- if (n <= sz) sz - n else sz
- }
- def apply(idx : Int) = (Seq.this.apply(idx + n))
- override def stringPrefix = Seq.this.stringPrefix + "D" + n
- }*/
-
/** Returns the longest prefix of this sequence whose elements satisfy
* the predicate <code>p</code>.
*
@@ -349,6 +373,7 @@ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Collection[A] {
result
}
override def projection : Seq.Projection[A] = new Seq.Projection[A] {
+ override def force : Seq[A] = Seq.this
def elements = Seq.this.elements
def length = Seq.this.length
def apply(idx : Int) = (Seq.this.apply(idx))
@@ -404,29 +429,5 @@ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Collection[A] {
/** Is <code>that</code> a slice in this?
*/
def containsSlice[B](that : Seq[B]) : Boolean = indexOf(that) != -1
-
- class Filter(p : A => Boolean) extends Seq.Projection[A] {
- override def stringPrefix = Seq.this.stringPrefix + "F"
- override def elements = Seq.this.elements.filter(p)
- override def apply(idx : Int) : A = {
- var jdx = 0
- val i = Seq.this.elements
- while (true) {
- val a = i.next
- if (p(a)) {
- if (jdx == idx) return a
- else jdx = jdx + 1
- }
- }
- throw new Predef.Error
- }
- override def length = {
- var sz = 0
- val i = Seq.this.elements
- while (i.hasNext) if (p(i.next)) sz = sz + 1
- sz
- }
- }
-
}
diff --git a/src/library/scala/Stream.scala b/src/library/scala/Stream.scala
index 59235e72a4..a3f8f0a1fb 100644
--- a/src/library/scala/Stream.scala
+++ b/src/library/scala/Stream.scala
@@ -23,8 +23,14 @@ import compat.StringBuilder
*/
object Stream {
+ /** a stream with a definite size */
+ trait Definite[+A] extends Stream[A] with Function0[Stream[A]] {
+ override def hasDefiniteSize = true
+ override def apply = this
+ }
+
/** The empty stream */
- val empty: Stream[Nothing] = new Stream[Nothing] {
+ val empty: Stream[Nothing] = new Definite[Nothing] {
override def isEmpty = true
def head: Nothing = throw new NoSuchElementException("head of empty stream")
def tail: Stream[Nothing] = throw new UnsupportedOperationException("tail of empty stream")
@@ -38,12 +44,13 @@ object Stream {
* @param tl The remaining elements of the result stream
*/
def apply[A](hd: A, tl: => Stream[A]) = new Stream[A] {
+ override def hasDefiniteSize = if (tlDefined) tlVal.hasDefiniteSize else super.hasDefiniteSize
override def isEmpty = false
def head = hd
private var tlVal: Stream[A] = _
- private var tlDefined = false
+ private def tlDefined = tlVal ne null
def tail: Stream[A] = {
- if (!tlDefined) { tlVal = tl; tlDefined = true }
+ if (!tlDefined) { tlVal = tl }
tlVal
}
protected def addDefinedElems(buf: StringBuilder, prefix: String): StringBuilder = {
@@ -176,6 +183,8 @@ trait Stream[+A] extends Seq.Projection[A] {
/** is this stream empty? */
override def isEmpty: Boolean
+ override def force : List[A] = toList
+
/** The first element of this stream
* @throws Predef.NoSuchElementException if the stream is empty.
*/
@@ -187,14 +196,16 @@ trait Stream[+A] extends Seq.Projection[A] {
def tail: Stream[A]
/** The length of this stream */
- def length: Int = if (isEmpty) 0 else tail.length + 1
+ override def length: Int = if (isEmpty) 0 else tail.length + 1
+ override def hasDefiniteSize = false
+
/** The stream resulting from the concatenation of this stream with the argument stream.
* @param rest The stream that gets appended to this stream
*/
- def append[B >: A](rest: => Stream[B]): Stream[B] =
- if (isEmpty) rest
- else Stream.cons(head, tail.append(rest))
+ override def append[B >: A](rest: => Iterable[B]): Stream[B] =
+ if (isEmpty) rest.toStream else Stream.cons(head, tail.append(rest))
+
/** An iterator returning the elements of this stream one by one.
*/
@@ -234,7 +245,7 @@ trait Stream[+A] extends Seq.Projection[A] {
* @return the element at position <code>n</code> in this stream.
* @throws Predef.NoSuchElementException if the stream is too short.
*/
- def apply(n: Int): A = drop(n).head
+ override def apply(n: Int): A = drop(n).head
/** Returns the <code>n</code> first elements of this stream, or else the whole
* stream, if it has less than <code>n</code> elements.
@@ -259,6 +270,7 @@ trait Stream[+A] extends Seq.Projection[A] {
loop(this, n)
}
+
/** Returns the longest prefix of this stream whose elements satisfy
* the predicate <code>p</code>.
*
@@ -388,7 +400,10 @@ trait Stream[+A] extends Seq.Projection[A] {
*/
override def flatMap[B](f: A => Iterable[B]): Stream[B] =
if (isEmpty) Stream.empty
- else Stream.fromIterator(f(head).elements).append(tail.flatMap(f))
+ else (f(head)).toStream append tail.flatMap(f)
+
+ override def toStream = this
+
/** A stream consisting of all elements of this stream in reverse order.
*/
diff --git a/src/library/scala/collection/mutable/Buffer.scala b/src/library/scala/collection/mutable/Buffer.scala
index 5180bbbe0c..9d35ab0bed 100644
--- a/src/library/scala/collection/mutable/Buffer.scala
+++ b/src/library/scala/collection/mutable/Buffer.scala
@@ -89,6 +89,13 @@ trait Buffer[A] extends AnyRef
*/
def ++(iter: Iterable[A]): Buffer[A] = { this ++= iter; this }
+ override def ++[B >: A](that : Iterable[B]) : Seq[B] = {
+ val buf = new ArrayBuffer[B]
+ this copyToBuffer buf
+ that copyToBuffer buf
+ buf
+ }
+
/** Appends a number of elements provided by an iterator
* via its <code>elements</code> method. The identity of the
* buffer is returned.
diff --git a/src/library/scala/runtime/RichString.scala b/src/library/scala/runtime/RichString.scala
index f63ee0a967..3c7d68f84f 100644
--- a/src/library/scala/runtime/RichString.scala
+++ b/src/library/scala/runtime/RichString.scala
@@ -25,6 +25,11 @@ final class RichString(val self: String) extends Proxy with RandomAccessSeq[Char
else if (until > self.length) self.length else until
new RichString(self.substring(from0, until0))
}
+ //override def ++ [B >: A](that: Iterable[B]): Seq[B] = {
+ override def ++[B >: Char](that : Iterable[B]) : RandomAccessSeq[B] = that match {
+ case that : RichString => new RichString(self + that.self)
+ case that => super.++(that)
+ }
override def take(until : Int) : RichString = slice(0, until)
override def drop(from : Int) : RichString = slice(from, self.length)
diff --git a/src/library/scala/runtime/RichStringBuilder.scala b/src/library/scala/runtime/RichStringBuilder.scala
index 8213cda8be..dbe822d627 100644
--- a/src/library/scala/runtime/RichStringBuilder.scala
+++ b/src/library/scala/runtime/RichStringBuilder.scala
@@ -13,7 +13,7 @@ package scala.runtime
import Predef._
-import scala.collection.mutable.Buffer
+import scala.collection.mutable.{Buffer,ArrayBuffer}
final class RichStringBuilder(val self : StringBuilder) extends RandomAccessSeq.Mutable[Char] with Proxy with Buffer[Char] {
override def length = self.length
@@ -26,7 +26,13 @@ final class RichStringBuilder(val self : StringBuilder) extends RandomAccessSeq.
case str : Array[Char] => self append str
case iter => super.++=(iter)
}
- override def ++(iter: Iterable[Char]): this.type = { this ++= iter; this }
+ override def ++(iter: Iterable[Char]): RichStringBuilder = { this ++= iter; this }
+ override def ++[B >: Char](that : Iterable[B]) : RandomAccessSeq[B] = {
+ val buf = new ArrayBuffer[B]
+ this copyToBuffer buf
+ that copyToBuffer buf
+ buf
+ }
override def insertAll(idx: Int, iter: Iterable[Char]): Unit = iter match {