Search code examples
scalatypesimplicits

Idiomatic way of branching depending on the existance of a type evidence in Scala


I find myself more than once writing the following ugly pattern:

class Something[A, B](implicit ev: A =:= B = null) {
  ...

  def doStuff {
    if (ev == null) ... // know that A is not the same as B
    else ...            // safely assume A is equal to B
  }
}

Even worse, when ev != null, I would sometimes write heresies such as someB.asInstanceOf[A].


Solution

  • Just use a type class,

    trait DoStuff[A, B] {
      def apply(): Unit
    }
    
    trait DoStuff0 {
      implicit def neDoStuff[A, B]: DoStuff[A, B] =
        new DoStuff[A, B] { def apply(): Unit = ... body of your ev == null case ...
    }
    
    object DoStuff extends DoStuff0 {
      implicit def eqDoStuff[A]: DoStuff[A, A] =
        new DoStuff[A, A] { def apply(): Unit = ... body of your ev != null case ...
    }
    
    class Something[A, B](implicit ds: DoStuff[A, B]) {
      ...
      def doStuff: Unit = ds()
    }