Created
September 24, 2011 08:27
-
-
Save kmizu/1239117 to your computer and use it in GitHub Desktop.
Yet another "generator" library implementation in Scala.
This file contains hidden or 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
//To compile this, "-P:continuations:enable" option is needed. | |
import scala.util.continuations._ | |
import scala.collection._ | |
object Generator { | |
abstract sealed class Computation[+A] | |
case class Yielded[A](k: Unit => Computation[A], v: A) extends Computation[A] | |
case object Done extends Computation[Nothing] | |
type yieldable[A] = cps[Computation[A]] | |
def make[A](body: (A => Unit @yieldable[A]) => Unit @yieldable[A]): Iterator[A] = new Iterator[A] { | |
val yields: A => Unit @yieldable[A] = {v => | |
shift{k: (Unit => Computation[A]) => Yielded(k, v) } | |
} | |
var thunk: Unit => Computation[A] = {x: Unit => | |
reset { | |
body(yields) | |
Done | |
} | |
} | |
var fetched: Boolean = false | |
var value: Option[A] = _ | |
def fetch(): Option[A] = { | |
if(!fetched) { | |
fetched = true | |
value = (thunk(()) match { | |
case Yielded(k, v) => | |
thunk = k | |
Some(v) | |
case Done => | |
None | |
}) | |
} | |
value | |
} | |
def hasNext(): Boolean = !fetch().isEmpty | |
def next: A = { | |
fetch() | |
fetched = false | |
value getOrElse (throw new NoSuchElementException("next on empty iterator")) | |
} | |
} | |
} |
This file contains hidden or 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
//To compile this, "-P:continuations:enable" option is needed. | |
import scala.util.continuations._ | |
import Generator._ | |
object GeneratorUsage { | |
def main(args: Array[String]) { | |
val x1 = make[Int]{yields => | |
yields(1) | |
println("X") | |
yields(2) | |
println("Y") | |
yields(3) | |
} | |
while(x1.hasNext) { | |
println("----") | |
println(x1.next) | |
} | |
val x2 = make[Int]{yields => | |
var i = 0 | |
while(i < 4){ | |
println("i = " + i) | |
yields(i) | |
i += 1 | |
} | |
} | |
while(x2.hasNext) { | |
println("****") | |
println(x2.next) | |
} | |
} | |
} |
This file contains hidden or 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
# Please see method callings which have side effects in GeneratorUsage.scala | |
---- | |
1 | |
X | |
---- | |
2 | |
Y | |
---- | |
3 | |
i = 0 | |
**** | |
0 | |
i = 1 | |
**** | |
1 | |
i = 2 | |
**** | |
2 | |
i = 3 | |
**** | |
3 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment