私は次の特性を持っています (ランク 2 ポリモーフィズムクリックのようなものを取得するには)
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 ですべて正常に動作します。
しかし、この map 関数で使用すると、typeTag[A].tpe は常に Any になります。