Skip to content

Instantly share code, notes, and snippets.

@rampion
Created April 4, 2012 11:13
Show Gist options
  • Save rampion/2300411 to your computer and use it in GitHub Desktop.
Save rampion/2300411 to your computer and use it in GitHub Desktop.
{-# LANGUAGE RankNTypes #-}
module Temp where
type Yielding a b = (a, PassiveIterable a b)
data PassiveIterable a b = Yield (Yielding a b) | End b
type ActiveIterable a b c = PassiveCoiterable a b -> c
type Awaiting a b = a -> PassiveCoiterable a b
data PassiveCoiterable a b = Await (Awaiting a b) | Return b
type ActiveCoiterable a b c = PassiveIterable a b -> c
data Result a b c = Full b c
| Underfull b (Awaiting a c)
| Overfull (Yielding a b) c
activate :: PassiveIterable a b -> PassiveCoiterable a c -> Result a b c
activate (End b) (Return c) = Full b c
activate (End b) (Await f) = Underfull b f
activate (Yield p) (Return c) = Overfull p c
activate (Yield (a,next)) (Await f) = activate next (f a)
activateIterable :: PassiveIterable a b -> ActiveIterable a c (Result a b c)
activateIterable = activate
activateCoiterable :: PassiveCoiterable a c -> ActiveCoiterable a b (Result a b c)
activateCoiterable = flip activate
passifyIterable :: (forall b. ActiveIterable a b c) -> PassiveIterable a c
passifyIterable = undefined
passifyCoiterable :: (forall b. ActiveCoiterable a b c) -> PassiveCoiterable a c
passifyCoiterable = undefined
import scala.util.continuations._
trait Coiterable[A] {
def isFull : Boolean
def consume( elem : A ) : Void
}
class Coiterable[A >: Null, B]( process : Iterable[A] => B ) {
sealed abstract class Status
case class AwaitingInput(withInput : WithInput) extends Status
case class Finished(b : B) extends Status
final class Report extends Function1[Status, (Option[A], Report)]
type WithInput = (Option[A], Report) => Status
class InvertingIterator(var report : Report) extends Iterator[A] {
private var found : Option[A] = None
def step {
if (found == None) {
val pair = reset { shift( (withInput : WithInput) => report(AwaitingInput(withInput))) }
found = pair._1
report = pair._2
}
}
def hasNext = { step ; !found.isEmpty }
def next = { step ; found.getOrElse(null : A) }
}
class InvertingIterable(report : Report) extends Iterable[A] {
val iter = new InvertingIterator( report )
def iterator = iter
}
private var status : Status = null
def setup {
status = reset { shift{ report : Report =>
val inv = new InvertingIterable(report)
var b : B = process(inv)
inv.iter.report(Finished(b))
Finished(b)
}}
}
def consume(elem : A) {
status = status match {
case AwaitingInput(withInput : WithInput) => reset { shift( withInput(Some(elem), _ )) }
case _ => status // already done
}
}
def cleanup : Option[B] = {
status match {
case Finished(b) => Some(b) // it's already done
case AwaitingInput(withInput : WithInput) =>
(reset { shift(withInput(None, _)) }) match { // try to finalize it
case Finished(b) => Some(b)
case _ => None
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment