I'm new to scala macros and I spent a couple of days trying to write my very first one. I have a problem with quasiquotes concatenation.
There is a list of case clauses, let's say the following:
val cases = cq"x => 1 " :: cq"_ => 0 " :: Nil
And I need to build a partial function from it. The problem is that I don't have an idea how to paste them in the final quasiquote. The documentation says I should do something like this:
q"{ case ..$cases }"
but it doesn't work if I do so.
Is there a way to build a PartialFunction from such a list?
Thanks for any help.
The following works for me with 2.11.2:
import scala.reflect.macros.Context
object Macros {
def partial: PartialFunction[Int, Int] = macro partialImpl
def partialImpl(c: Context): c.Expr[PartialFunction[Int, Int]]= {
import c.universe._
val cases = cq"x => 1 " :: cq"_ => 0 " :: Nil
val pf = q"{ case ..$cases } : PartialFunction[Int, Int]"
c.Expr[PartialFunction[Int, Int]](pf)
}
}
Then you can call Macros.partial(1)
, for example, or Macros.partial.isDefinedAt(2)
.
Note that in order to make this work, I had to explicitly use PartialFunction[Int, Int]
in the quasiquote q"{ case ..$cases } : PartialFunction[Int, Int]"
. It didn't work without the explicit type definition (it otherwise assumes PartialFunction[Any, Int]
).
Here is the specification for quasiquote Syntax for partial functions. It works as a pure syntax tree, but apparently cannot be interpreted as a typed expression except PartialFunction[Any, T]
by a macro unless the type is made explicit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With