Skip to content

Instantly share code, notes, and snippets.

@arnolddevos
Created September 11, 2010 05:36
  • Star 14 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save arnolddevos/574873 to your computer and use it in GitHub Desktop.
Idea for generator and suspendable wrapper
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 {
def generator[A]( f: (A => Unit @ suspendable) => Unit @ suspendable): Iterator[A] = {
val g = new Generator[A]
reset { f(g) }
g
}
trait SuspendableForeach[A]{ def foreach( f: A => Unit @suspendable ): Unit @ suspendable }
def suspendable[A]( ible: Iterable[A]) = new SuspendableForeach[A] {
def foreach( f: A => Unit @ suspendable ) : Unit @ suspendable = {
val i = ible.iterator
while( i.hasNext ) f(i.next)
}
}
}
object Main {
import Generator._
def example = generator[String] { yld =>
yld( "first" )
for( i <- suspendable(List(1,2,3)); j <- suspendable(List(4,5,6))) {
yld((i*j).toString)
}
yld("last")
}
def main(args: Array[String]) {
for( a <- example ) println(a)
}
}
@kbloom
Copy link

kbloom commented Sep 15, 2010

Using new{ def foreach() = ... } in suspendable() creates a structural type which is dispatched with reflection. Depending on the circumstances, that can be rather slow. Create a named trait e.g.
trait GeneratorForeachable[A]{ def foreach( f: A => Unit @suspendable ) }
and create an anyonymous subclass of that in suspendable()

def suspendable[A](ible: Iterable[A]) = new GeneratorForeachable[A]{... 

@arnolddevos
Copy link
Author

thanks Ken - fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment