Skip to content

Instantly share code, notes, and snippets.

@JavadocMD
Last active April 26, 2016 22:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JavadocMD/fd367ea7ca1a6e8ac907a7e2c69f01c6 to your computer and use it in GitHub Desktop.
Save JavadocMD/fd367ea7ca1a6e8ac907a7e2c69f01c6 to your computer and use it in GitHub Desktop.
Application of type classes for intersecting Shapes, inspired by http://eli.thegreenplace.net/2016/a-polyglots-guide-to-multiple-dispatch
// Define our shapes.
trait Shape
class Rectangle extends Shape
class Ellipse extends Shape
class Triangle extends Shape
object Shape {
// The method we'll call to perform an intersection.
def intersect[A <: Shape, B <: Shape](a: A, b: B)(implicit ev: Intersection[A,B]): Unit = {
ev(a, b)
}
// Implementations of this type class will perform the specialized intersection logic.
trait Intersection[-A <: Shape, -B <: Shape] {
def apply(a: A, b: B): Unit
}
// Make sure Scala considers this type class last by mixing it in as a separate trait.
trait IntersectionLowPriority {
implicit object IntersectShSh extends Intersection[Shape, Shape] {
def apply(s1: Shape, s2: Shape) = println("Shape x Shape")
}
}
// These type classes will be preferred.
object Intersection extends IntersectionLowPriority {
implicit object IntersectReEl extends Intersection[Rectangle, Ellipse] {
def apply(r: Rectangle, e: Ellipse) = println("Rectangle x Ellipse")
}
implicit object IntersectReRe extends Intersection[Rectangle, Rectangle] {
def apply(r1: Rectangle, r2: Rectangle) = println("Rectangle x Rectangle")
}
}
}
object Main {
import Shape._
import Shape.Intersection._ // Bring the implicits into scope
def main(args: Array[String]): Unit = {
val r1 = new Rectangle()
val r2 = new Rectangle()
val e = new Ellipse()
val t = new Triangle()
intersect(r1, e)
intersect(r1, r2)
intersect(r1, t)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment