我具有以下特征(要获得 2 级多态性click)
type Id[A] = A
trait ~>[F[_], G[_]] {
def apply[A](a: F[A]): G[A]
def isDefinedAt[A](a: A): Boolean}
以及将部分函数转换为此特征的函数:
implicit def pft[B: ClassTag](f: PartialFunction[B, B])= new (Id ~> Id) {
def apply[A](a: A): A = f(a.asInstanceOf[B]).asInstanceOf[A]
def isDefinedAt[A: ClassTag](a: A)(implicit ev2: ClassTag[A]) : Boolean = /*type check*/
f.isDefinedAt(a.asInstanceOf[B]) }
所以我的问题是 isDefinedAt 方法。我必须在运行时检查 A 是否是 B 的实例。a.isInstanceOf[B] 由于类型擦除而不起作用。
我尝试使用 TypeTag/ClassTag 和 B 效果很好,但 A 的类型总是 Any。
那么,如何检查 A 是否是 B 的实例?
更新:我在这段代码中使用它:
def map[A](f: Id ~> Id, x: A): A =
{
val y = x match {
//many matches more on my own data structures
case l : List[_] => l.map(map(f,_))
case m : Map[_,_] => m.map(map(f,_))
case (a,b) => (map(f,a),map(f,b))
case a => a
}
if (f.isDefinedAt(y))
f(y).asInstanceOf[A]
else
y.asInstanceOf[A]
}
如果我直接使用 ~>,那么 typeTag[A].tpe <:< typeTag[B].tpe 一切正常。
但是如果我将它与这个映射函数一起使用,typeTag[A].tpe 总是 Any。