scala macros scala-macros scala-quasiquotes

Correspondencia de literales de función con quasiquotes en scala.



macros scala-macros (1)

Con el último plugin de Paradise para 2.10 y en vainilla 2.11 puedes hacerlo de esta manera:

val q"(..$args) => $body" = f.tree

Acabo de probarlo con el proyecto de ejemplo de paraíso con Macros.scala siguiente:

import language.experimental.macros import scala.reflect.macros.Context object Macro { def apply(f: Any): Any = macro impl def impl(c: Context)(f: c.Expr[Any]) = { import c.universe._ val q"(..$args) => $body" = f.tree println(s"args = $args, body = $body") c.Expr(q"()") } }

Y Test.scala :

object Test extends App { Macro((x: Int) => x + 1) }

Puede leer más sobre el manejo de árboles de funciones con cuasicotas en el capítulo correspondiente de la guía de cuasicotas .

Esta pregunta es similar en motivación a mi pregunta anterior (aunque se trata de un problema que encontré en un contexto diferente ).

Puedo hacer coincidir patrones en una función literal con bastante facilidad sin quasiquotes:

import scala.reflect.macros.Context import scala.language.experimental.macros object QQExample { def funcDemo(f: Int => String) = macro funcDemo_impl def funcDemo_impl(c: Context)(f: c.Expr[Int => String]) = { import c.universe._ f.tree match { case Function(ps, body) => List(ps, body) foreach println case _ => c.abort( c.enclosingPosition, "Must provide a function literal." ) } c.literalUnit } }

Que funciona así:

scala> QQExample.funcDemo((a: Int) => a.toString) List(val a: Int = _) a.toString()

Ahora supongamos que quiero usar cuasicotas para hacer el mismo tipo de partido de manera más flexible. Lo siguiente también coincidirá con esa función, e imprime lo que esperaríamos.

case q"($x: $t) => $body" => List(x, t, body) foreach println

Pero si quiero especificar el tipo en el patrón, no coincide:

case q"($x: Int) => $body" => List(x, body) foreach println

Y ninguno de los siguientes incluso compilará:

case q"$p => $body" => List(p, body) foreach println case q"($p) => $body" => List(p, body) foreach println case q"..$ps => $body" => List(ps, body) foreach println case q"(..$ps) => $body" => List(ps, body) foreach println

¿Es posible especificar el tipo de un parámetro al hacer coincidir en una función literal con cuasiquotes, o hacer coincidir en un número desconocido de parámetros?