[snip]
> But my experience with pattern matching in Scala has
> s shown me that it solves that problem and more without
> the magic.
If you have:
trait Points { def test( p : Points ) : Boolean }
case class Point( x : Int, y : Int ) extends Points {
override def test( p : Points ) = p match {
case Point( px, py ) => x == px && y == py
case _ => false
}
}
And you can't change Point (e.g. third party library) then you have two options for Point3D, either:
case class Point3D( x : Int, y : Int, z : Int ) extends Points {
override def test( p : Points ) = p match {
case Point( px, py ) => x == px && y == py && z == 0
case Point3D( px, py, pz ) => x == px && y == py && z == pz
case _ => false
}
}
or
case class Point3D2( override val x : Int, override val y : Int, z : Int ) extends Point( x, y ) {
override def test( p : Points ) = p match {
case Point3D2( px, py, pz ) => x == px && y == py && z == pz
case _ => super.test( p )
}
}
(For the second case there are a number of options for test - but none of them work).
The following tests should all print true:
val p = new Point( 2, 1 )
val p3D = new Point3D( 2, 1, 0 )
val p23D = new Point3D( 2, 1, 2 )
println( "Option 1 - Point3D extends Points (note s)" )
println( p.test( p ) )
println( p.test( p3D ) )
println( p3D.test( p ) )
println( p3D.test( p3D ) )
println( !p.test( p23D ) )
println( !p3D.test( p23D ) )
val p3D2 = new Point3D2( 2, 1, 0 )
val p23D2 = new Point3D2( 2, 1, 2 )
println( "Option 2 - Point3D2 extends Point (no s)" )
println( p.test( p ) )
println( p.test( p3D2 ) )
println( p3D2.test( p ) )
println( p3D2.test( p3D2 ) )
println( !p.test( p23D2 ) )
println( !p3D2.test( p23D2 ) )
Unfortunately the output is:
Option 1 - Point3D extends Points (note s)
true
false
true
true
true
true
Option 2 - Point3D2 extends Point (no s)
true
true
true
true
false
true
With multiple dispatch you can get the correct answer by simply writing 3 methods.