同一模块中的隐式具体化
Implicit materialization in the same module
我有一个参数化的class喜欢
class Test[T]{
//...
}
object Test{
implicit def materializeTest[T]: Test[T] = macro impl[T]
def impl[T: c.WeakTypeTag](c: blackbox.Context) = //...
}
如果使用同一模块中的具体化隐式,则会引发错误:
macro implementation not found
但问题是将单个 class 提取到单独的模块中看起来非常丑陋和麻烦。也许有一些“众所周知的解决方法”可以避免这种情况?也许 shapeless 在这里会有帮助?
更新:
scalaVersion in ThisBuild := "2.13.2"
这是我的最小示例:
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
object Main {
sealed trait Adt
case object Adt1 extends Adt
case object Adt2 extends Adt
trait Test[Adtt <: Adt] {
def restrict(restrictions: List[Int]): List[Int]
}
object Test {
def apply[Adtt <: Adt](implicit ev: Test[Adtt]): Test[Adtt] = ev
implicit def implicitMaterializer[
Adtt <: Adt
]: Test[Adtt] = macro impl[Adtt]
def impl[Adtt <: Adt: c.WeakTypeTag](
c: blackbox.Context
): c.Expr[Test[Adtt]] = {
import c.universe._
c.Expr[Test[Adtt]](q"""???""")
}
}
def main(args: Array[String]): Unit = {
Test[Adt1.type].restrict(List(1, 2, 3))
}
}
这会导致以下错误:
[error] Main.scala:32:9: macro implementation not found: implicitMaterializer
[error] (the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)
您可以提取到一个单独的模块,不是 Test
,而是 TestMacro
核心
import scala.language.experimental.macros
class Test[T]
object Test {
implicit def materializeTest[T]: Test[T] = macro TestMacro.impl[T]
}
implicitly[Test[Int]] // compiles
宏
import scala.reflect.macros.blackbox
object TestMacro {
def impl[T: c.WeakTypeTag](c: blackbox.Context) = {
import c.universe._
q"new Test[${weakTypeOf[T]}]"
}
}
丑陋与否,但宏实现必须在应用之前进行编译。
这在 Scala 3 中得到了改进
Shapeless 只是隐藏了一些预定义的标准宏集,它对您自己的宏没有帮助。
我有一个参数化的class喜欢
class Test[T]{
//...
}
object Test{
implicit def materializeTest[T]: Test[T] = macro impl[T]
def impl[T: c.WeakTypeTag](c: blackbox.Context) = //...
}
如果使用同一模块中的具体化隐式,则会引发错误:
macro implementation not found
但问题是将单个 class 提取到单独的模块中看起来非常丑陋和麻烦。也许有一些“众所周知的解决方法”可以避免这种情况?也许 shapeless 在这里会有帮助?
更新:
scalaVersion in ThisBuild := "2.13.2"
这是我的最小示例:
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
object Main {
sealed trait Adt
case object Adt1 extends Adt
case object Adt2 extends Adt
trait Test[Adtt <: Adt] {
def restrict(restrictions: List[Int]): List[Int]
}
object Test {
def apply[Adtt <: Adt](implicit ev: Test[Adtt]): Test[Adtt] = ev
implicit def implicitMaterializer[
Adtt <: Adt
]: Test[Adtt] = macro impl[Adtt]
def impl[Adtt <: Adt: c.WeakTypeTag](
c: blackbox.Context
): c.Expr[Test[Adtt]] = {
import c.universe._
c.Expr[Test[Adtt]](q"""???""")
}
}
def main(args: Array[String]): Unit = {
Test[Adt1.type].restrict(List(1, 2, 3))
}
}
这会导致以下错误:
[error] Main.scala:32:9: macro implementation not found: implicitMaterializer
[error] (the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)
您可以提取到一个单独的模块,不是 Test
,而是 TestMacro
核心
import scala.language.experimental.macros
class Test[T]
object Test {
implicit def materializeTest[T]: Test[T] = macro TestMacro.impl[T]
}
implicitly[Test[Int]] // compiles
宏
import scala.reflect.macros.blackbox
object TestMacro {
def impl[T: c.WeakTypeTag](c: blackbox.Context) = {
import c.universe._
q"new Test[${weakTypeOf[T]}]"
}
}
丑陋与否,但宏实现必须在应用之前进行编译。
这在 Scala 3 中得到了改进
Shapeless 只是隐藏了一些预定义的标准宏集,它对您自己的宏没有帮助。