Dealing with type erasure warning

I’ve been getting some type erasure warnings for a long time, and I finally decided to try to deal with them.

[warn] /Users/jimka/Repos/regular-type-expression/cl-robdd-scala/src/main/scala/treereduce/ListSpecificTreeReduce.scala:44:51: abstract type pattern A is unchecked since it is eliminated by erasure
[warn]         val reduced: List[A] = li.map { case (b1: A, b2: A) => f(b1, b2) }
[warn]                                                   ^

I’ve changed the code to something else which eliminates the warning, and is more cryptic. I don’t understand why it is better. Can someone explain?

I’ve basically replaced map{case (b1: A, b2: A) => f(b1, b2)} with map(f1) where f1 is defined as def f1(aa:(A,A)):A = f(aa._1, aa._2). Why is this better? Why is the compiler happy with one and not with the other?

BTW isn’t there already function which takes an n-ary function and returns a unary function which takes an n-tuple? Would using that function make the code clearer or more obscure?

  def pairWiseFold[A](z: A)(mList: List[A], f: (A, A) => A): A = {
    val (pairs: List[(A, A)], leftover: Option[A]) = paired(mList)
    if (mList.isEmpty)
      z
    else {
      @scala.annotation.tailrec
      def recur(li: List[(A, A)], maybeB: Option[A]): A = {

        // val reduced: List[A] = li.map { case (b1: A, b2: A) => f(b1, b2) }

        // replaced the line above with these two lines to eliminate compiler warning
        def f1(aa:(A,A)):A = f(aa._1, aa._2)
        val reduced: List[A] = li.map(f1)

        if (reduced.tail.isEmpty)
          ... stuff deleted
        else {
          ... stuff deleted
        }
      }
      recur(pairs, leftover)
    }
  }
1 Like

Just leave the type pattern out: case (b1, b2) => ... li is a List[(A, A)], so the compiler can figure out the types of b1 and b2 on its own. With the type pattern, the compiler complains because it could not constrain the match accordingly due to type erasure - which is not required here, anyway, since the match is total.

2 Likes

The function you are referring to is tupled, which is a method on function types, so you should be able to replace

li.map { case (b1: A, b2: A) => f(b1, b2) }

with

li.map(f.tupled)
1 Like