Solution (source code)

= Solution

These methods consume the receiver's remaining sequence; `exists` stops as soon as it finds a witness:

``
trait RichIter[T] extends Iter[T] {
  def foreach(f: T => Unit): Unit = {
    while (hasNext) f(next())
  }

  def exists(p: T => Boolean): Boolean = {
    while (hasNext) {
      if (p(next())) return true
    }
    false
  }

  def foldLeft[U](x: U)(f: (U,T) => U): U = {
    var result = x
    while (hasNext) result = f(result, next())
    result
  }
}
``

After $j$ consumed elements, `foreach` has invoked its callback on exactly that prefix, `exists` has found no witness in it unless it has already returned, and the <left fold> accumulator is the fold of that prefix in its original order. These <loop invariants> prove the finite-sequence results. On an infinite sequence, `exists` may still terminate when it reaches a witness; a full traversal or fold generally does not. To retain the original cursor, a caller can invoke the operation on a suitable copy.