Here's the closest thing I could work out. It uses shiftR to reify the continuation rather than reset it, uses a foldRight to construct the suspended continuation chain, uses a shift/reset block to get the continuation after the suspension, and an "animate" method to kick off the suspended continuation.
import scala.collection.mutable.HashMap
import scala.util.continuations._
val sessions = new HashMap[Int, (Unit=>Unit, Int)]
val map = new HashMap[Int, Int]
def ask(pair:(String, Int)) = pair match {
case (prompt, index) => shiftR { (ret: Unit => Unit) => {
val id = sessions.size
printf("%s\nrespond with: submit(0x%x, ...)\n", prompt, id)
sessions += id -> (ret, index)
()
}}
}
def submit(id: Int, addend: Int): Unit = {
sessions.get(id) match {
case Some((continue, index)) => { map.put(index, addend); continue() }
}
}
def sum(m:HashMap[Int,Int]) : Int = {
m.fold[(Int, Int)]((0, 0))((a, b) => (0, {a._2+b._2}))._2
}
type Suspended = ControlContext[Unit,Unit,Unit]
class AnimateList(l:List[Suspended]) {
def suspend(k: => Unit) = (c: Unit) => k
def animate(k:Unit => Unit): Unit = {
l.foldRight(k)(
(elem: Suspended, acc: Unit => Unit) => suspend(elem.fun(acc, ex => ())))()
}
}
implicit def listToAnimateList(l:List[Suspended]) = new AnimateList(l)
reset {
val conts = List("First?","Second?","Third?").zipWithIndex.map(ask)
shift { conts.animate }
println(sum(map))
}