Search code examples
scalaconstructorapplytyped

Scala: Typed method that returns object of the provided Type


Good day everyone,

I need to create a Typed Class with a Typed function to parse an Array[String] and returns an Array[OutputType]

class Data()
class IntData(var element: Int) extends Data
class BoolData(var element: Boolean) extends Data

class ArrayParser[OutputType <: Data]() {
    def parse(in: Array[String]): Array[OutputType] = {
        in.map(s => parseRecord(s))
    }
}

I tried:

    def parse(in: Array[String]): Array[OutputType] = {
        in.map(s => {
            import scala.reflect.runtime.universe._
            if (typeOf[OutputType] =:= typeOf[IntData])
                new IntData(s.toInt)
            else
                new BoolData(s.toBoolean)
        })
    }

but I got the error: Expression of type Array[Data] doesn't conform to expected type Array[OutputType]

What can I do to achieve the requirements?

Thanks for your help.


Solution

  • Why not define a Typeclass to parse the string into the relevant type?

    trait Parser[T <: Data] { 
      def parse(s: String): T
    }
    
    implicit val intParser: Parser[IntData] = ???
    implicit val boolParser: Parser[BoolData] = ???
    
    def parse[T <: Data : Parser](a: Array[String]): Array[T] = { 
      val p = implicitly[Parser[T]]
      a.map(s => p.parse(s))
    }
    

    Also I would advise making Data a sealed trait and it's implementations case classes.