Created
May 16, 2010 07:52
-
-
Save kmizu/402748 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//This file should be compiled unser scala 2.8.0.RC2 with -P:continuations:enable | |
import scala.util.continuations._ | |
import scala.collection._ | |
trait Generator[+A] extends Traversable[A] { | |
def moveNext(): Boolean | |
def current: A | |
def foreach[U](f: A => U): Unit = { | |
while(moveNext()) { | |
f(current) | |
} | |
} | |
} | |
object Generator { | |
type susp = cps[Any] | |
def pass: Unit @susp = shiftUnit0[Unit, Any](()) | |
implicit def unit2cps(u: Unit): Unit @susp = pass | |
def make[A](body: (A => Unit @susp) => Unit @susp): Generator[A] = new Generator[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 value: A = _ | |
def moveNext(): Boolean = { | |
val result = thunk() | |
result match { | |
case (k, v) => | |
thunk = k.asInstanceOf[(Unit => Any)] | |
value = v.asInstanceOf[A] | |
true | |
case None => | |
false | |
} | |
} | |
def current: A = value | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//This file should be compiled unser scala 2.8.0.RC2 with -P:continuations:enable | |
import Generator._ | |
/* Existing higher-order functions in the standard library don't handle | |
* capture of continuations. Then, I implemented such functions. | |
*/ | |
object Control { | |
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](t: Iterable[A])(f: A => (Unit @susp)) | |
: Unit @susp = { | |
val it = t.iterator | |
def loop: Unit @susp = { | |
if(it.hasNext) { | |
f(it.next()) | |
loop | |
} | |
} | |
loop | |
} | |
} | |
import Control._ | |
import scala.xml._ | |
object User { | |
def main(args: Array[String]) { | |
// Generator which enumerates numbers from 1 to 10 | |
val g1 = make[Int] {yields => | |
upto(1, 10) {i => | |
yields(i) | |
} | |
} | |
// Generator which enumerates XML elements which are | |
// descendants of n | |
def elements(n: Node) = make[Elem]{yields => | |
def eachElem(n: Node): Unit @susp = { | |
n match { case e:Elem => yields(e); case _ => } | |
each(n.child)(eachElem(_)) | |
} | |
eachElem(n) | |
} | |
val g2 = elements( | |
<html> | |
<head> | |
<title>Scala Delimited Continuation Test</title> | |
</head> | |
<body> | |
<p>Test</p> | |
</body> | |
</html> | |
) | |
g1.foreach(println) | |
g2.foreach(e => println(e.label)) //要素名を出力 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment