Skip to content

Instantly share code, notes, and snippets.

@pchiusano
Created November 16, 2012 04:25
Show Gist options
  • Save pchiusano/4084045 to your computer and use it in GitHub Desktop.
Save pchiusano/4084045 to your computer and use it in GitHub Desktop.
Machines with upstream communication
package fpinscala.streamingio
/**
Machine takes binary type constructor now.
Requests are an F[X,Y] and an X, for some X and Y.
*/
trait Machine[F[_,_],A] {
def vary[F0[X,Y] >: F[X,Y], A0 >: A] =
this.asInstanceOf[Machine[F0,A0]]
}
object Machine {
case class Await[F[_,_],S,A,B](
request: F[S,A], arg: S,
recv: A => Machine[F,B],
fallback: Machine[F,B]) extends Machine[F,B]
case class Emit[F[_,_],A](
head: A,
tail: Machine[F,A]) extends Machine[F,A]
case object Fail extends Machine[Nothing,Nothing]
def await[A,B](recv: A => Machine[One[A]#f, B]):
Machine[One[A]#f, B] =
Await(One[A]().Get, (), recv, Fail.vary)
def await1[A,B,C](recv: A => Machine[Tee[A,B]#f, C]):
Machine[Tee[A,B]#f, C] =
Await(Tee[A,B]().Fst, (), recv, Fail.vary)
def await2[A,B,C](recv: B => Machine[Tee[A,B]#f, C]):
Machine[Tee[A,B]#f, C] =
Await(Tee[A,B]().Snd, (), recv, Fail.vary)
}
case class One[A]() {
trait f[X,Y]
case object Get extends f[Unit,A]
}
case class Tee[A,B]() {
trait f[X,Y]
case object Fst extends f[Unit,A]
case object Snd extends f[Unit,B]
}
object Files {
trait f[X,Y]
case object Lines extends f[String,Handle[String]]
case class Lit[A] extends f[List[A],Handle[A]]
case class Close[A]() extends f[Handle[A],Unit]
case class Read[A]() extends f[Handle[A],A]
}
trait Handle[A] {
def next: Option[A] // stateful - but should be private to driver
def peek: Option[A]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment