More Scala coolness

The problem: given a java.util.Iterator<E> (which may be non-strict and infinite), create a new scala.collection.Seq[E] which fulfills the contract of Seq but does not violate the laziness of the underlying Iterator.

Scala is perfect for this - a combination of anonymous classes and closures, along with using implicits to perform the conversion automatically, allow us to use any Java iterator with all the rich Scala collection functionality we want.

 
  implicit def iterator2LazySeq[E](coll: Iterator[E]): Seq[E] = new Seq[E] {
    self =>

    // use an indexed seq to memoize because most of our operations depend
    // heavily on indexing
    var memoizedSeq: IndexedSeq[E] = IndexedSeq()
    // what's the position of the cursor?
    var cursorIndex = -1

    def length = throw new UnsupportedOperationException("Length not supported on LazySeqs")

    def apply(i: Int): E = {
      // fast forward, loading elements and memoizing them as we go
      while (i >= memoizedSeq.length) {
        cursorIndex = cursorIndex + 1;
        memoizedSeq = memoizedSeq :+ coll.next
      }

      memoizedSeq(i)
    }

    // anonymous iterator class required by Seq
    def iterator = new Iterator[E] {
      // just keep an index, use it to index into self
      var iteratorIndex = -1

      def next: E = {
        iteratorIndex += 1
        
        self(iteratorIndex)
      }

      def hasNext = {
        // we only need to check the underlying collection if we haven't
        // already memoized the next element
        if (iteratorIndex < cursorIndex)
          true
        else
          coll.hasNext
      }
    }

  }

If you find any bugs, please let me know!