1
votes

I want to get rid of type erasure warnings of this sample code:

val a: Seq[Any] = Seq(1)
a match {
  case b: Seq[Int] => b.map(c => println(2 * c) )
  case _ => println("Not matched")
}

It compiles and works ok, but with a warning:

Warning:(31, 13) non-variable type argument Int in type pattern Seq[Int] (the underlying of Seq[Int]) is unchecked since it is eliminated by erasure case b: Seq[Int] => b.map(c => println(2 * c) ) ^

Do you have any simple solution for avoiding the erasure in this case?

What have I tried so far (accorting to this):

val a: Seq[Any] = Seq(1)
a match {
  case b@Seq(_:Int) => b.map(c => println(2 * c) )
  case _ => println("Not matched")
}

But it won't compile because c is now of type Any.

I believe there are several solution to this problem. I will accept the simplest one.

3
Note that your approach breaks parametricity - dl.dropboxusercontent.com/u/7810909/talks/parametricity/….Kevin Meredith

3 Answers

1
votes

I'm not sure the this is a simplest solution but I think it's better to match over type with TypeTags

def matchOnList[A: TypeTag](l: List[A]) = typeOf[A] match {
    case t if t =:= typeOf[Int] =>
      l.asInstanceOf[List[Int]].foreach(c => println(2 * c))
    case _ => println("Not matched")
  }

val a = List(1)

matchOnList(a)
0
votes

This

  case b: Seq[Int @unchecked] => b.map(c => println(2 * c))

will get rid of the warning. But it won't solve underlying problem of erasure. Seq("1") will match this case.

0
votes

I had the same problem, I ended up doing something like this (didn't find anything prettier):

val a: Seq[Any] = Seq(1)
a match {
  case b: Seq[_] => b.map(c =>
    c match {
      case s: Int => print(2 * s)
      case _ => print("Not matched")
    })
  case _ => print("Not matched")
}