title: How to transform and apply a partial function using Scala Macros?
body: <p>I want to implement a Scala macro which takes a partial function, performs some transformations on the patterns of the function, and then applies it to a given expression.</p>
  
  <p>To do so, I started with the following code:</p>
  
  <pre><code>def myMatchImpl[A: c.WeakTypeTag, B: c.WeakTypeTag](c: Context)(expr: c.Expr[A])(patterns: c.Expr[PartialFunction[A, B]]): c.Expr[B] = {
    import c.universe._
  
    /*
     * Deconstruct the partial function and select the relevant case definitions.
     * 
     * A partial, anonymus function will be translated into a new class of the following form:
     * 
     * { @SerialVersionUID(0) final &lt;synthetic&gt; class $anonfun extends scala.runtime.AbstractPartialFunction[A,B] with Serializable {
     * 
     *     def &lt;init&gt;(): anonymous class $anonfun = ...
     *
     *     final override def applyOrElse[...](x1: ..., default: ...): ... = ... match {
     *       case ... =&gt; ...
     *       case (defaultCase$ @ _) =&gt; default.apply(x1)
     *     }
     *
     *     def isDefined ...
     *   }
     *   new $anonfun()
     * }: PartialFunction[A,B]
     *
     */
    val Typed(Block(List(ClassDef(a, b, x, Template(d, e, List(f, DefDef(g, h, i, j, k, Match(l, allCaseDefs)), m)))), n), o) = patterns.tree
  
    /* Perform transformation on all cases */
    val transformedCaseDefs: List[CaseDef] = allCaseDefs map {
      case caseDef =&gt; caseDef // This code will perform the desired transformations, now it's just identity
    }
  
    /* Construct anonymus partial function with transformed case patterns */
    val result = Typed(Block(List(ClassDef(a, b, x, Template(d, e, List(f, DefDef(g, h, i, j, k, Match(l, transformedCaseDefs)), m)))), n), o)
    // println(show(result))
  
    c.Expr[B](q"$result($expr)")
  }
  </code></pre>
  
  <p>I deconstruct the partial function, select the case definitions of the applyOrElse function, perform the desired transformation on each definition, and put everything back together. The macro is invoked like this:</p>
  
  <pre><code>def myMatch[A, B](expr: A)(patterns: PartialFunction[A, B]): B = macro myMatchImpl[A,B]
  </code></pre>
  
  <p>Unfortunately, this doesn't work as expected. Using the macro in a simple example</p>
  
  <pre><code>def test(x: Option[Int]) = myMatch(x){
    case Some(n) =&gt; n
    case None    =&gt; 0
  }
  </code></pre>
  
  <p>results in the following error message:</p>
  
  <pre><code>object creation impossible, since method isDefinedAt in trait PartialFunction of type (x: Option[Int])Boolean is not defined
  </code></pre>
  
  <p>This is a bit confusing, since printing the generated partial function yields</p>
  
  <pre><code>({
    final &lt;synthetic&gt; class $anonfun extends scala.runtime.AbstractPartialFunction[Option[Int],Int] with Serializable {
      def &lt;init&gt;(): anonymous class $anonfun = {
        $anonfun.super.&lt;init&gt;();
        ()
      };
      final override def applyOrElse[A1 &lt;: Option[Int], B1 &gt;: Int](x2: A1, default: A1 =&gt; B1): B1 = ((x2.asInstanceOf[Option[Int]]: Option[Int]): Option[Int] @unchecked) match {
        case (x: Int)Some[Int]((n @ _)) =&gt; n
        case scala.None =&gt; 0
      };
      final def isDefinedAt(x2: Option[Int]): Boolean = ((x2.asInstanceOf[Option[Int]]: Option[Int]): Option[Int] @unchecked) match {
        case (x: Int)Some[Int]((n @ _)) =&gt; true
        case scala.None =&gt; true
        case (defaultCase$ @ _) =&gt; false
      }
    };
    new $anonfun()
  }: PartialFunction[Option[Int],Int])
  </code></pre>
  
  <p>which clearly defines the isDefinedAt method.</p>
  
  <p>Does anybody has an idea, what's the problem here and how to do this right?</p>