strange interaction of generic types, type casting, and inheritence

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

strange interaction of generic types, type casting, and inheritence

John Williams
Is there any way to write this code without defining a helper
function? The issue I've found is that casting to Seq requires a type
parameter, and the type parameter has to be declared with the method,
and adding a type parameter to a method changes its signature for
overriding purposes. I tried casting to Seq and Seq[_] instead of
Seq[A] but neither of those works either.

abstract class Base {
  def isEmptySeq(x: Any): Boolean
}

class Derived extends Base {
  // Override can't have type param.
  override def isEmptySeq(x: Any) = isEmptySeq1(x)

  // Helper function.
  def isEmptySeq1[A](x: Any) = {
    x.isInstanceOf[Seq[A]] &&
    x.asInstanceOf[Seq[A]].length == 0
  }

  // Alternate helper function.
  def isEmptySeq2[A](x: Any) = x match {
    case s: Seq[A] => s.length == 0
    case _ => false
  }
}
Reply | Threaded
Open this post in threaded view
|

Re: strange interaction of generic types, type casting, and inheritence

Iulian Dragos-2
John Williams wrote:

> Is there any way to write this code without defining a helper
> function? The issue I've found is that casting to Seq requires a type
> parameter, and the type parameter has to be declared with the method,
> and adding a type parameter to a method changes its signature for
> overriding purposes. I tried casting to Seq and Seq[_] instead of
> Seq[A] but neither of those works either.
>
> abstract class Base {
>   def isEmptySeq(x: Any): Boolean
> }
>
> class Derived extends Base {
>   // Override can't have type param.
>   override def isEmptySeq(x: Any) = isEmptySeq1(x)
>
>   // Helper function.
>   def isEmptySeq1[A](x: Any) = {
>     x.isInstanceOf[Seq[A]] &&
>     x.asInstanceOf[Seq[A]].length == 0
>   }

You can simply cast to Seq[Any]. Since Seq is covariant in it's type
parameter, it should work fine even if we had runtime types. With the
current erasure scheme this is not the case, so anyway, type tests don't
take type parameters into account.

def isEmptySeq(x: Any) = {
     x.isInstanceOf[Seq[Any]] &&
     x.asInstanceOf[Seq[Any]].length == 0
}

Iulian