jibril12
jibril12

Reputation: 83

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

Upvotes: 0

Views: 93

Answers (2)

Andrey Tyukin
Andrey Tyukin

Reputation: 44908

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))

Upvotes: 1

Brian McCutchon
Brian McCutchon

Reputation: 8584

You can't conditionally return one of two different types like that. Consider using Either instead:

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

Upvotes: 0

Related Questions