public
Last active

  • Download Gist
block2stream
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
import scala.util.continuations._
 
class Generator[A] extends Iterator[A] with (A => Unit @ suspendable) {
private var a: Option[A] = None
private var k: Option[Unit => Unit] = None
def next = {
val a0 = a.get
val k0 = k.get
a = None
k = None
k0()
a0
}
def hasNext = k.isDefined
def apply(a0: A): Unit @ suspendable = {
a = Some(a0)
shift { k0: (Unit => Unit) => k = Some(k0) }
}
}
 
object Generator {
 
trait SuspendableIterable[A]{
def foreach( f: A => Unit @ suspendable ) : Unit @ suspendable
}
 
def generator[A]( f: (A => Unit @ suspendable) => Unit @ suspendable): Iterator[A] = {
val g = new Generator[A]
reset { f(g) }
g
}
def suspendable[A]( ible: Iterable[A]) = new SuspendableIterable[A] {
def foreach( f: A => Unit @ suspendable ) : Unit @ suspendable = {
val i = ible.iterator
while( i.hasNext ) f(i.next)
}
}
}
 
object Main {
import Generator._
 
def data(block: Int => Unit) {
for (i <- 0 to 10) block(i)
}
 
def main(args: Array[String]) {
val dataStream = generator[Int] { yld =>
data { i => yld(i) }
}.toStream
 
dataStream.foreach { println(_) }
}
}

Data needs to be changed this way for it to work:

def data(block: Int => Unit @ suspendable): Unit @ suspendable = {
  var i = 0
  while(i <= 10) {
    block(i)
    i += 1
  }
}

So, no, you can't take a non-suspendable method and suspend it using delimited continuations. It just doesn't work that way.

That's the problem, because I can't change the implementation of data function.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.