Квазицитаты для нескольких параметров и списков параметров

Quasiquotes удивительныони делают написание макросов в Scala чрезвычайно менее болезненным, и, по моему опыту, они почти всегда работают именно так, как я »буду ожидать. И что лучше всего, онитеперь доступнокак плагин в Scala 2.10.

Этот вопрос о небольшой проблеме, с которой я столкнулся при написанииэтот блог, Это'в моем списке вещей, чтобы посмотреть, когда я найду несколько минут, но я решил, чтоЯ бы опубликовал это здесь на случай, если кто-то другой может побить меня этим, и помочь другим людям, которые сталкиваются с тем же вопросом.

Предположим, у меня есть список списков пар имя-тип:

val pss = List(
  List(newTermName("x") -> typeOf[Int], newTermName("y") -> typeOf[Char]),
  List(newTermName("z") -> typeOf[String])
)

Я хочу превратить их в дерево, которое выглядит так:

def foo(x: Int, y: Char)(z: String) = ???

Следующее работает просто отлично:

q"def bar(${pss.head.head._1}: ${pss.head.head._2}) = ???"

То есть он строит следующее дерево:

def bar(x: Int) = ???

Что говорит о том, что я должен быть в состоянии написать что-то вроде этого:

val quoted = pss.map(_.map { case (n, t) => q"$n: $t" })

q"def foo..${quoted.map(ps => q"($ps)")} = 1"

Или немного проще, с несколькими параметрами в одном списке параметров:

q"def baz(..${quoted.head}) = ???"

Ни то, ни другое не работаетЯ получаю такие ошибки:

:28: error: type mismatch;
 found   : List[c.universe.Typed]
 required: List[c.universe.ValDef]
           q"def baz(..${quoted.head}) = ???"
                                ^

Справедливо-Я вижу, как бы это выглядело квазиквотеру, как япостроение типизированных выражений вместо определения параметров вquoted, Ни одна из очевидных вещей, которые я мог бы попробовать, не сработала (добавив= _, явно набрав квазицитатуру какValDef, так далее.).

Я знаю, что могу создать определения параметров вручную:

val valDefs = pss.map(
  _.map {
    case (n, t) => ValDef(Modifiers(Flag.PARAM), n, TypeTree(t), EmptyTree)
  }
)

А теперьbaz Версия (с одним списком параметров) работает:

q"def baz(..${valDefs.head}) = ???"

Но неfoo версия (та, с несколькими списками параметров).

Итак, здесь есть два вопроса. Во-первых, как я могу использовать квази-кавычки, чтобы превратить пару типа имя в параметрValDef вне контекста списка параметров в кавычках? И во-вторых, как я могу превратить список списков определений параметров в несколько списков параметров?

Это'Достаточно легко вернуться к ручному построению AST для всего этого проклятого (см.мой пост для примера), но яя хотел бы иметь возможность использовать квазицитаты вместо этого.

Ответы на вопрос(1)

Ваш ответ на вопрос