Created
June 3, 2016 23:19
-
-
Save paulp/3e5f1a16f48334bfe8819aaf3b3bc69b to your computer and use it in GitHub Desktop.
Another in the endless parade.
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
package p | |
/** Super basic map/flatMap fusion ADT. | |
*/ | |
sealed trait View[A] { | |
def map[B](f: A => B): View[B] = CView(this, Mapped(f)) | |
def flatMap[B](f: A => View[B]): View[B] = CView(this, FlatMap(f)) | |
def foreach(f: A => Unit): Unit = this match { | |
case IdView(xs) => xs foreach f | |
case Optimize(xs) => xs foreach f | |
case CView(xs, Mapped(g)) => xs foreach (g andThen f) | |
case CView(xs, FlatMap(g)) => xs foreach (x => g(x) foreach f) | |
} | |
} | |
final case class IdView[A, B](xs: Vector[A]) extends View[A] | |
final case class CView[A, B](prev: View[A], op: Op[A, B]) extends View[B] | |
sealed trait Op[A, B] | |
final case class FlatMap[A, B](f: A => View[B]) extends Op[A, B] | |
final case class Mapped[A, B](f: A => B) extends Op[A, B] | |
/** Super simple peephole optimizer. | |
* | |
* Can you spot the type error? Don't worry, neither can Scala. | |
*/ | |
object Optimize { | |
def unapply[A](v: View[A]): Option[View[A]] = v match { | |
case CView(CView(xs, Mapped(f)), Mapped(g)) => Some(CView(xs, Mapped(f andThen g))) | |
case CView(CView(xs, FlatMap(f)), FlatMap(g)) => Some(CView(xs, FlatMap(f andThen g))) | |
case _ => None | |
} | |
} | |
/** No warnings, just throw the ClassCastException. | |
*/ | |
object Run { | |
def view[A](xs: A*): View[A] = IdView(xs.toVector) | |
def main(argv: Array[String]): Unit = { | |
view(1, 2, 3) map (_ + 1) map (_ + 1) foreach println // ok | |
view(1, 2, 3) flatMap (x => view(x)) foreach println // ok | |
// java.lang.ClassCastException: p.IdView cannot be cast to java.lang.Integer | |
view(1, 2, 3) flatMap (x => view(x)) flatMap (x => view(x)) foreach println | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment