【发布时间】:2015-02-05 07:33:03
【问题描述】:
我有一个带有类似签名的宏
def generateSomething[A] = macro ...
也就是说,它接受一个类型参数。该类型应该是一个案例类,因此它的伴生对象中总是有相应的apply 方法。
除其他外,此宏会生成此apply 方法的调用,例如,对于此类:
case class A(x: Int, y: String)
将生成以下调用:
A.apply(someFunction[Int], someFunction[String])
我从apply签名中提取someFunction调用的参数类型。
一切都很好,除非 A 被参数化:
case class A[T](x: Int, y: T)
使用我目前的方法,为generateSomething[A[String]] 生成以下内容:
A.apply[String](someFunction[Int], someFunction[T])
这显然是无效的。
但是,在知道apply 的所有类型参数之后,我不知道如何获取它的参数。也就是说,我不知道如何确定
generateSomething[A[String]]
生成
A.apply[String](someFunction[Int], someFunction[String])
而不是上面的部分。有可能吗?
更新
我想我应该重新提出这个问题。
假设有一个类
case class A[T1, ..., Tn](x1: A1, ..., xm: Am)
其中Ai 可以依赖于Tk 的任意子集。例子:
// T1 = T
// A1 = Int, A2 = T
case class B[T](x: Int, y: T)
// T1 = U, T2 = V
// A1 = Map[U, V], A2 = List[V]
case class C[U, V](m: Map[U, V], l: List[V])
// T1 = W
// A1 = W, A2 = W
case class D[W](t: W, u: W)
// No Ts
// A1 = String, A2 = Double
case class E(v: String, w: Double) // no type parameters at all
我需要编写一个宏,它接受类型参数 A 并扩展为带有预处理参数的 A.apply 方法调用:
myMacro[A[U1, ..., Un]]
// expands to
A.apply[U1, ..., Un](preprocess[A1], ..., preprocess[An])
Uk 这里是实际类型参数,它们被替换而不是Tk。例如(使用上面的类):
myMacro[B[String]] -> B.apply[String](preprocess[Int], preprocess[String])
myMacro[C[Int, Double]] -> C.apply[Int, Double](preprocess[Map[Int, Double]], preprocess[List[Double]])
myMacro[D[Long]] -> D.apply[Long](preprocess[Long], preprocess[Long])
myMacro[E] -> D.apply(preprocess[String], preprocess[Double])
你看,apply 参数类型可以依赖于类型参数。虽然宏知道这些参数(因为它总是用具体类型调用),但我不知道如何将这些参数“通过”“传递”给apply 函数以使preprocess 类型参数正确.
更新 2
Here 大致就是我目前拥有的。
【问题讨论】:
标签: scala generics scala-macros