1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import util.continuations._
//import collection.mutable.ListBuffer
import scala.collection.IterableLike
import scala.collection.generic.CanBuildFrom
import scala.language.implicitConversions
import scala.language.reflectiveCalls

sealed trait Zipper[A] { def zipUp: Seq[A] }
case class ZDone[A](val zipUp: Seq[A]) extends Zipper[A]
case class Z[A](current: A, forward: Option[A] => Zipper[A]) extends Zipper[A] {
  def zipUp = forward(None).zipUp
}

implicit def richIterable[X, A, Repr](xs: IterableLike[A, Repr]) = new {
  def suspendable = new {
    def foreach(yld: A => Unit @cps[X]): Unit @cps[X]={
      val it = xs.iterator
      while (it.hasNext) yld(it.next)
    }
    def map[B, That](f: A => B @cps[X])(implicit bf: CanBuildFrom[Repr, B, That]): That @cps[X]={
      val b = bf(xs.repr)
      foreach(x => { b += f(x); () })
      b.result
    }
  }
}

object Zipper {
  // A = A, B = C = X = Zipper[A]
  def apply[A](seq: Seq[A]): Zipper[A] = reset {
    // Compiler can't figure out types, so explicitly call richIterable
    val l = for (a <- richIterable[Zipper[A], A, Seq[A]](seq).suspendable) yield shift {
      (k: A => Zipper[A]) =>
      Z(a, (a1: Option[A]) => k(a1.getOrElse(a)))
    }
    ZDone(l) // Compiler bug prevents doing this on a single line
  } 
}