scalagenericsreturn-current-type

Create object at runtime which have the same internal contents


I am performing a repetitive task of creating a object that has same internal contents and hence thought of creating a generic method that would help me achieve this.

The internal object is as follows

case class Data(value: Int)

I have a base trait as follows

trait Base

There are a couple of classes that extend this trait

case class A(data: Data) extends Base
case class B(data: Data) extends Base
case class C(data: Data) extends Base

The generic method that I am trying to write to create the object

def getObject[T <: Base](data: Data, t: T) = {
  T(data)
}

However, while trying to do so, I get a compile-time error saying that

Cannot resolve symbol T

Can you please let me know what I am missing in this method implementation. Note:- This is a very simplistic implementation of what I am trying to do in my code.


Solution

  • Consider typeclass solution for compile-time safety

    final case class Data(value: Int)
    final case class A(data: Data)
    final case class B(data: Data)
    final case class C(data: Data)
    
    trait BaseFactory[T] {
      def apply(data: Data): T
    }
    
    object BaseFactory {
      def apply[T](data: Data)(implicit ev: BaseFactory[T]): T = ev.apply(data)
      implicit val aBaseFactory: BaseFactory[A] = (data: Data) => A(data)
      implicit val bBaseFactory: BaseFactory[B] = (data: Data) => B(data)
      implicit val cBaseFactory: BaseFactory[C] = (data: Data) => C(data)
    }
    
    val data = Data(42)
    BaseFactory[A](data)   // res0: A = A(Data(42))
    BaseFactory[B](data)   // res1: B = B(Data(42)) 
    BaseFactory[C](data)   // res2: C = C(Data(42))