asInstanceOf with parameterized type


#1

I have a rule trait that will be mixed-in to another trait called A for applying rule.

trait A[T] {
    def map(data: T)
}

trait Rule[E] {
    def rule: E => Boolean
}

class AImpl extends A[String] with Rule[String] ... { override def rule ... }

// desired logic 
val a =  new AImpl()  //  // get a instance of A
if(a.isInstanceoOf[Rule[String]])    
    Seq(...).filter(a.asInstanceOf[Rule[String]]rule) 

When Rule parameterized with String I know I can directly cast using a.asInstanceOf[Rule[String]]. However I will have other parameterized type later on. But asInstanceOf[Rule[…]] has limited (stated something like https://stackoverflow.com/questions/6686992/scala-asinstanceof-with-parameterized-types)

Is there any recommended way to circumvent this problem? Mainly to achieve the effect that I can dynamically cast Rule with different parameterized type like

if(a.isInstanceOf[Rule[SomeType]]) a.asInstanceOf[Rule[SomeType]] ... // SomeType is the dest type to which I would like to cast.

Thanks


#2

Hello,

Two solutions come to my mind:

(1) If the there are only a small fixed set of types that can be parameters, you could create a subtype for each, e.g.

class StringRule extends Rule[String]

(2) Obtain a TypeTag for the parameter, get the Type from it and store it.

Best, Oliver


#3

You may want to consider designing your API such that the compiler does this check for you. For example:

def desiredLogic(a: Rule[String]) = Seq(/*...*/).filter(a.rule)
// or
def desiredLogic[T](a: Rule[T], xs: Seq[T]) = xs.filter(a.rule)

#4

I decided to go with subclass e.g. StringRule extends Rule[String] tentatively. Then observe (and perhaps update this thread) how it works because at this stage not many variants needed to be dealt with.

Thanks again for all your help!