Search code examples
scaladiamond-problem

Scala diamond prob, find class name from instance of class D


I have four traits A, B, C and D in the typical diamond problem hierarchy. I have implemented a method calculate in trait A which checks the instance of callerObject, performs some calculation and returns trait A type object. calculate method is successfully able to check the instanceType of callerObject when callerObject belongs to trait B or C but doesn't work for object of trait D and I get the following class cast exception:

java.lang.ClassCastException: packageName.B$$anon$1 cannot be cast to packageName.D

Can you please suggest way forward, how can I check the Type of the object from trait D in method of trait A.

PS: I am new to Scala.


Solution

  • With pattern matching the order of the case statements matters. Make sure that the most specific class is always matched at the top. For example if B extends A and C extends B, it means that objects of C will always match anything that looks for either B or A, etc.

    Here is a toy example that can better explain the solution:

    sealed trait A {
       def calculate(i: A) = i match {
          case _:D => "d" // Make sure the D is checked first!
          case _:B => "b"
          case _:C => "c"
          // If you want to match for A make sure it is added last
       }
    }
    trait B extends A
    trait C extends A
    trait D extends B with C
    

    Here is an example in the REPL:

    val b = new B{}
    val c = new C{}
    val d = new D{}
    
    b.calculate(b)
    res> "b"
    b.calculate(c)
    res> "c"
    b.calculate(d)
    res> "d"