Created
April 4, 2012 11:13
-
-
Save rampion/2300411 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
{-# 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 |
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
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