Skip to content

Instantly share code, notes, and snippets.

@kmizu
Created September 16, 2010 13:31
Show Gist options
  • Save kmizu/582421 to your computer and use it in GitHub Desktop.
Save kmizu/582421 to your computer and use it in GitHub Desktop.
//scalac -P:continuations:enable
import scala.util.continuations._
import scala.collection._
object Generator {
type susp = cps[Any]
def make[A](body: (A => Unit @susp) => Unit @susp): Iterator[A] = new Iterator[A] {
val yields: A => Unit @susp = {v =>
shift{k: (Unit => Any) => (k, v):Any }
}
var thunk: Unit => Any = {x: Unit =>
reset {
body(yields)
None
}
}
var fetched: Boolean = false
var value: Option[A] = _
def fetch(): Option[A] = {
if(!fetched) {
fetched = true
value = (thunk(()) match {
case (k, v) =>
thunk = k.asInstanceOf[(Unit => Any)]
Some(v.asInstanceOf[A])
case None =>
None
})
}
value
}
def hasNext(): Boolean = !fetch().isEmpty
def next: A = {
fetch()
fetched = false
value getOrElse (throw new NoSuchElementException("next on empty iterator"))
}
}
}
object Control {
import Generator._
def upto[A](from: Int, to: Int)(f: Int => A @susp): Unit @susp = {
if(from <= to) { f(from); upto(from + 1, to)(f) }
}
def each[A](iterable: Iterable[A])(f: A => (Unit @susp)): Unit @susp = {
val it = iterable.iterator
def loop: Unit @susp = {
if(it.hasNext) {
f(it.next())
loop
}
}
loop
}
def toIterator[A](f: (A => Unit @susp) => Unit @susp) = make[A]{yields =>
f{a => yields(a)}
}
}
object User {
import Generator._
import Control._
def main(args: Array[String]) {
val x = make[Int]{yields =>
upto(1, 10){i => yields(i)}
}
val y = toIterator(upto(1, 20))
println(x.toList)
println(y.toList)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment