Skip to content

Instantly share code, notes, and snippets.

@bmc
Created April 30, 2010 18:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmc/385610 to your computer and use it in GitHub Desktop.
Save bmc/385610 to your computer and use it in GitHub Desktop.
import scala.util.continuations._
import java.io.File
object Test2
{
sealed trait Iteration[+T]
case class Yield[+T](result: T, next: () => Iteration[T])
extends Iteration[T]
case object Done extends Iteration[Nothing]
// Adapted from http://stackoverflow.com/questions/2201882/implementing-yield-yield-return-using-scala-continuations/2215182#2215182
def trampoline[T](body: => Iteration[T]): Iterator[T] =
{
def loop(thunk: () => Iteration[T]): Stream[T] =
{
thunk.apply match
{
case Yield(result, next) => Stream.cons(result, loop(next))
case Done => Stream.empty
}
}
loop(() => body).iterator
}
def iterator[T](body: => Unit @cps[Iteration[T]]):
Iterator[T] =
{
trampoline
{
reset[Iteration[T], Iteration[T]]
{
body
Done
}
}
}
def genyield[T](result: T): Unit @cps[Iteration[T]] = shift
{
k: (Unit => Iteration[T]) => Yield(result, () => k(()))
}
def recurse(dir: File): Iterator[File] = iterator[File]
{
def doList(list: List[File]): Unit @cps[Iteration[File]] =
{
list match
{
case Nil =>
case one :: tail =>
genyield(one)
if (one.isDirectory)
doList(one.listFiles.toList)
else
doList(Nil)
doList(tail)
}
}
doList(dir.listFiles.toList)
}
def main(args: Array[String]) =
{
val r = recurse(new File(args(0)))
println(r.next)
println(r.next)
println(r.next)
for (f <- r) println(f)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment