Skip to content

Instantly share code, notes, and snippets.

@halcat0x15a
Created December 18, 2015 05:36
Show Gist options
  • Save halcat0x15a/9d2575f61d88c4559213 to your computer and use it in GitHub Desktop.
Save halcat0x15a/9d2575f61d88c4559213 to your computer and use it in GitHub Desktop.
import scala.annotation.tailrec
sealed abstract class Queue[F[_], A, B] {
def :+[C](f: B => F[C]): Queue[F, A, C] =
new Node(this, new Leaf(f))
def ++[C](that: Queue[F, B, C]): Queue[F, A, C] =
new Node(this, that)
def view: View[F, A, B]
}
case class Leaf[F[_], A, B](arrow: A => F[B]) extends Queue[F, A, B] {
def view: View[F, A, B] =
new One(arrow)
}
case class Node[F[_], A, B, T](left: Queue[F, A, T], right: Queue[F, T, B]) extends Queue[F, A, B] {
def view: View[F, A, B] = {
@tailrec
def go[F[_], A, B](x: Queue[F, A, Any], y: Queue[F, Any, B]): View[F, A, B] = {
x match {
case Leaf(v) => new Cons(v, y)
case Node(l, r) => go[F, A, B](l, new Node(r, y))
}
}
go(left.asInstanceOf[Queue[F, A, Any]], right.asInstanceOf[Queue[F, Any, B]])
}
}
sealed abstract class View[F[_], A, B]
case class One[F[_], A, B](arrow: A => F[B]) extends View[F, A, B]
case class Cons[F[_], A, B, T](arrow: A => F[T], queue: Queue[F, T, B]) extends View[F, A, B]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment