Last active
April 26, 2016 22:50
-
-
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
This file contains hidden or 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
// 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