Контекст : я пытаюсь написать макрос, который статически осведомлен о нефиксированном количестве типов. Я пытаюсь передать эти типы в качестве параметра одного типа, используя HList
. Это будет называться m[ConcreteType1 :: ConcreteType2 :: ... :: HNil]()
. Затем макрос создает оператор соответствия, который требует, чтобы некоторые комплименты были найдены во время компиляции, немного похоже на то, как json serialiser может требовать неявных кодировщиков. У меня есть рабочая реализация макроса при использовании фиксированного числа параметров типа, как показано ниже:
def m[T1, T2](): Int = macro mImpl[T1, T2]
def mImpl[T1: c.WeakTypeTag, T2: c.WeakTypeTag](c: Context)(): c.Expr[Int] = {
import c.universe._
val t = Seq(
weakTypeOf[T1],
weakTypeOf[T2]
).map(c => cq"a: $c => externalGenericCallRequiringImplicitsAndReturningInt(a)")
val cases = q"input match { case ..$t }"
c.Expr[Int](cases)
}
Вопрос : Если у меня есть WeakTypeTag[T]
для некоторых T <: HList
, есть ли способ превратить это в Seq[Type]
?
def hlistToSeq[T <: HList](hlistType: WeakTypeTag[T]): Seq[Type] = ???
Мой инстинкт - написать рекурсивное совпадение, которое превращает каждый T <: HList
в H :: T
или HNil
, но Я не думаю, что такой тип соответствия существует в scala.
. Я хотел бы услышать о любом другом способе получения списка типов произвольного размера в макрос, учитывая, что нужен Seq[Type]
, а не Expr[Seq[Type]]
, так как мне нужно отобразить их в макросе.
Способ написания подобного «макроса» в Dotty тоже был бы интересен - я надеюсь, что это » там будет проще, но еще не до конца изучено.
Редактировать (уточнение) : причина, по которой я использую макрос, в том, что я хочу пользователя библиотеки, которую я запись для предоставления коллекции типов (возможно, в форме HList
), которые библиотека может перебирать и ожидать это относится к. Я говорю библиотека, но она будет скомпилирована вместе с использованием, чтобы макросы работали; в любом случае его следует использовать с разными коллекциями типов. Это немного сбивает с толку, но я думаю, что я решил это немного - мне просто нужно иметь возможность создавать макросы, которые могут работать со списками типов.