У меня есть макрос с подписью какКак заменить фактические аргументы типа в общем методе для получения окончательных типов аргументов значения?
def generateSomething[A] = macro ...
То есть, он принимает параметр типа. Тип, как ожидается, будет классом case, поэтому он всегда имеет соответствующий метод apply
в своем сопутствующем объекте.
Этот макрос, среди всего прочего, генерирует вызов этого apply
метода, так что, к примеру, для этого класса:
case class A(x: Int, y: String)
следующий вызов будет сгенерирован:
A.apply(someFunction[Int], someFunction[String])
I извлечение параметров параметров для someFunction
звонков с apply
подпись.
Все нормально, если не 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])
, а не кусок выше. Является ли это возможным?
Update
Я думаю, что я должен переформулировать вопрос.
Предположим, что существует класс
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
были правильными.
Update 2
Here неплотно, что я в настоящее время.
Извините, но я не понимаю, как это может помочь. См. Мое обновление. Мне нужен общий механизм для обработки классов case с произвольными параметрами типа и произвольным количеством аргументов значений. –
'$ t' - тип arg, показанный в приложении с квазикодированием. Вы можете использовать список аргументов в любом случае. В вашем редактировании замените 'List.apply' на' preprocess', и это пример, который я дал. Или, покажите нам, что вы пробовали, и мы скажем вам, что вы сделали неправильно. –
Ваша программа работает специально для типа 'X', который имеет параметр одного типа и параметр одиночного значения. Мне нужно работать с типами с произвольным количеством типов и параметров типа. Хорошо, я скоро отправлю свой код. –