在宏扩展中从前缀重新安装类型参数
Reinstalling type parameters from prefix in a macro expansion
下面应该显示问题:
class Container[A](val xs: List[A]) {
def foo(fun: A => A)(implicit ord: Ordering[A]): List[A] =
macro ContainerMacros.fooImpl // how to pass `xs`?
}
object ContainerMacros {
def fooImpl(c: blackbox.Context)
(fun: c.Expr[Nothing => Any])
(ord: c.Expr[Ordering[_]]): c.Expr[List[Nothing]] = {
import c.universe._
reify {
// val cont = c.prefix.splice.asInstanceOf[Container[_]]
// cont.xs.map(fun.splice).sorted(ord.splice)
???
}
}
}
也就是说,似乎没有办法将 A
作为类型参数添加到 fooImpl
(如果我这样做,编译器会抱怨)。所以我必须删除它,但问题是如何让 reify
中的内容按预期方式工作,即如何重新引入缺少的类型参数 A
.
这是一次尝试:
def fooImpl(c: blackbox.Context)
(fun: c.Expr[Nothing => Any])
(ord: c.Expr[Ordering[_]]): c.Expr[List[Nothing]] = {
import c.universe._
reify {
val ext = c.prefix.splice.asInstanceOf[ExtensionTest[_]]
import ext.{A1 => A}
val extC = ext .asInstanceOf[ExtensionTest[A]]
val funC = fun.splice.asInstanceOf[A => A]
val ordC = ord.splice.asInstanceOf[Ordering[A]]
val xs = extC.xs.asInstanceOf[List[A]] // computer says no
xs.map(funC).sorted(ordC)
}
}
xs.map(funC)
不适用于那些传奇的 scalac 错误消息之一:
Error:(27, 16) type mismatch;
found : _ => Any where type _
required: Any => ?
xs.map(funC).sorted(ordC)
实际上感谢@edmundnoble 通过 Scala Gitter 频道的回答:
您可以在 impl 调用中添加类型参数,因此可以将 A
从 Container
传递给宏扩展:
class Container[A](val xs: List[A]) {
def foo(fun: A => A)(implicit ord: Ordering[A]): List[A] =
macro ContainerMacros.fooImpl[A]
}
object ContainerMacros {
def fooImpl[A](c: blackbox.Context)
(fun: c.Expr[A => A])
(ord: c.Expr[Ordering[A]])
(implicit t: c.WeakTypeTag[A]): c.Expr[List[A]] = {
import c.universe._
reify {
val extC = c.prefix.splice.asInstanceOf[Container[A]]
val funC = fun.splice
val ordC = ord.splice
val xs = extC.xs
xs.map(funC).sorted(ordC)
}
}
}
下面应该显示问题:
class Container[A](val xs: List[A]) {
def foo(fun: A => A)(implicit ord: Ordering[A]): List[A] =
macro ContainerMacros.fooImpl // how to pass `xs`?
}
object ContainerMacros {
def fooImpl(c: blackbox.Context)
(fun: c.Expr[Nothing => Any])
(ord: c.Expr[Ordering[_]]): c.Expr[List[Nothing]] = {
import c.universe._
reify {
// val cont = c.prefix.splice.asInstanceOf[Container[_]]
// cont.xs.map(fun.splice).sorted(ord.splice)
???
}
}
}
也就是说,似乎没有办法将 A
作为类型参数添加到 fooImpl
(如果我这样做,编译器会抱怨)。所以我必须删除它,但问题是如何让 reify
中的内容按预期方式工作,即如何重新引入缺少的类型参数 A
.
这是一次尝试:
def fooImpl(c: blackbox.Context)
(fun: c.Expr[Nothing => Any])
(ord: c.Expr[Ordering[_]]): c.Expr[List[Nothing]] = {
import c.universe._
reify {
val ext = c.prefix.splice.asInstanceOf[ExtensionTest[_]]
import ext.{A1 => A}
val extC = ext .asInstanceOf[ExtensionTest[A]]
val funC = fun.splice.asInstanceOf[A => A]
val ordC = ord.splice.asInstanceOf[Ordering[A]]
val xs = extC.xs.asInstanceOf[List[A]] // computer says no
xs.map(funC).sorted(ordC)
}
}
xs.map(funC)
不适用于那些传奇的 scalac 错误消息之一:
Error:(27, 16) type mismatch; found : _ => Any where type _ required: Any => ? xs.map(funC).sorted(ordC)
实际上感谢@edmundnoble 通过 Scala Gitter 频道的回答:
您可以在 impl 调用中添加类型参数,因此可以将 A
从 Container
传递给宏扩展:
class Container[A](val xs: List[A]) {
def foo(fun: A => A)(implicit ord: Ordering[A]): List[A] =
macro ContainerMacros.fooImpl[A]
}
object ContainerMacros {
def fooImpl[A](c: blackbox.Context)
(fun: c.Expr[A => A])
(ord: c.Expr[Ordering[A]])
(implicit t: c.WeakTypeTag[A]): c.Expr[List[A]] = {
import c.universe._
reify {
val extC = c.prefix.splice.asInstanceOf[Container[A]]
val funC = fun.splice
val ordC = ord.splice
val xs = extC.xs
xs.map(funC).sorted(ordC)
}
}
}