Search code examples
scalashapelessalgebraic-data-types

Using parameterized branch of ADT in function


Here is the code:

sealed trait Tr
final case class A(a: String) extends Tr
final case class B(b: String) extends Tr

def markWithType[Type <: Tr](tr: Type): Type = tr match {
  //Compile error
  //Expression of type A doesn't conform to expected type Type
  case A(a) => A("A:" + a) 

  //Compile error
  //Expression of type B doesn't conform to expected type Type
  case B(b) => B("B:" + b)
}

The problem is it does not compile. I want to preserve Type <: Tr and make it compiling successfully. Is there a way to do that?

I'm pretty sure shapeless can be helpful here.


Solution

  • You can go with simple overloading.

    sealed trait Tr {
      def markWithType: Tr
    }
    
    final case class A(a: String) extends Tr {
      override def markWithType: A = A(s"A: ${a}")
    }
    
    final case class B(b: String) extends Tr {
      override def markWithType: B = B(s"B: ${b}")
    }
    

    Another option would be a typeclass but I believe that would be an overkill in this case.