0
問題を示す例:部分適用
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
object Test {
def foo1[A, B]: Unit = macro impl[A, B]
def foo2[A]: Unit = macro impl[A, Option[Int]]
def impl[A: c.WeakTypeTag, B: c.WeakTypeTag](c: blackbox.Context): c.Expr[Unit] = {
import c.universe._
c.echo(c.enclosingPosition, s"A=${weakTypeOf[A]}, B=${weakTypeOf[B]}")
reify(())
}
}
/*
scala> Test.foo1[Int, Option[Int]]
<console>:12: A=Int, B=Option[Int]
Test.foo1[Int, Option[Int]]
^
scala> Test.foo2[Int]
<console>:12: A=Int, B=Option[A] // <--- Expected: A=Int, B=Option[Int]
Test.foo2[Int]
*/
我々はfoo2
で、具体的なタイプを失ったのはなぜですか?それはfoo1
と非常によく似ています。
PS:私はベストではないかもしれない解決策見つけた:
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
import scala.reflect.runtime.universe.TypeTag
object Test {
def foo1[A, B](implicit bTag: TypeTag[B]): Unit = macro impl[A, B]
def foo2[A](implicit bTag: TypeTag[Option[Int]]): Unit = macro impl[A, Option[Int]]
def impl[A: c.WeakTypeTag, B](c: blackbox.Context)(bTag: c.Expr[TypeTag[B]]): c.Expr[Unit] = {
import c.universe._
c.echo(c.enclosingPosition, s"A=${weakTypeOf[A]}, B=${bTag.actualType.typeArgs.head}")
reify(())
}
}
/*
scala> Test.foo1[Int, Option[Int]]
<console>:12: A=Int, B=Option[Int]
Test.foo1[Int, Option[Int]]
^
scala> Test.foo2[Int]
<console>:12: A=Int, B=Option[Int]
Test.foo2[Int]
*/
をしかし、質問に対する答えはまだ私には興味深いものです。