Q:

Wrong type after type casting using asInstanceOf Scala

I'm trying to type cast from the super type java.io.Serializable to List[String] or List[List[String]]. I used asInstanceOf method as seen below but the type remains as the java.io.Serializable. 
Input Data:
val singleList = "apple:orange"

val nestedList = "apple:orange;James:Mike"

val size = 8

Functions:
def x(s:String): List[String] = {

    s.split(":").toList
}

def s (s1: String) : List[ List[ String ]] = {

   s1.split(";").toList.map(x=> x.split(":").toList)
}

val f = if(size <= 8) {

       x(singleList).asInstanceOf[List[String]]

     } else{

        s(nestedList).asInstanceOf[List[List[String]]]
      }

Desired Output type:
List[String] or List[List[String]]
Thanks

A:

Unfortunately, "List[String] or List[List[String]]" is not a valid type. You have the following choices:

wrap it into Either[List[String], List[List[String]]],
explicitly ascribe f to be of type List[_]
just accept that the most specific type that can be inferred is List[java.io.Serializable], and work with that.

You could of course define or to be an infix operator that is just an alias for Either:
import util.{Either, Left, Right}

type or[A, B] = Either[A, B]

val f: List[String] or List[List[String]] = {
  if (size <= 8) Left(x(singleList))
  else Right(s(nestedList))
}

but it does not have any significant advantages over using Either directly.
If you decide to use Either / or, you will have to work with it in all subsequent steps too. For example, here is how you would format f as single line or multi-line table:
def formatAsTable(t: List[String] or List[List[String]]): String = t match {
  case Left(singleLine) => singleLine.mkString(",")
  case Right(multiLine) => multiLine.map(_.mkString(",")).mkString("\n")
}

println(formatAsTable(f))

