This question is similar in motivation to my previous question (although it's about a problem I ran into in a different context).
I can pattern match on a function literal pretty easily without 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
}
}
Which works like this:
scala> QQExample.funcDemo((a: Int) => a.toString)
List(val a: Int = _)
a.toString()
Now suppose I want to use quasiquotes to do the same kind of match more flexibly. The following will also match on that function, and prints what we'd expect.
case q"($x: $t) => $body" => List(x, t, body) foreach println
But if I want to specify the type in the pattern, it doesn't match:
case q"($x: Int) => $body" => List(x, body) foreach println
And none of the following even compile:
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
Is it possible to specify the type of a parameter when matching on a function literal with quasiquotes, or to match on an unknown number of parameters?
With latest paradise plugin for 2.10 and in vanilla 2.11 you can do it this way:
I've just tested it out with paradise example project with following
Macros.scala
:And
Test.scala
:You can read in more about handling of function trees with quasiquotes in corresponding chapter of quasiquote guide.