2013-09-01 9 views
25

この質問は、私のprevious questionと同じです(different contextで遭遇した問題です)。スカラでの関数のリテラルとの一致

私は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 
    } 
} 

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

は今、私は試合の同じ種類を行うためにquasiquotesを使用するとしますより柔軟に。次は、その関数にもマッチし、私たちが期待しているものを出力します。

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

しかし、私はパターンでタイプを指定したい場合は、それが一致しません:

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

そして、次のどれをも、コンパイル:

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 

はそれが可能です関数リテラルをクォーコクツトと照合するときにパラメータの型を指定するか、未知数のパラメータを照合するか?

+9

これはバグです。最後のコードブロックのすべてのパターンは、単一引数の匿名関数で機能するはずです。修正がマスターにマージされたときに通知を受けるには、[SI-7803](https://issues.scala-lang.org/browse/SI-7803)に従ってください。 –

+0

@DenShabalin:ありがとうございます! –

+5

修正は2.11プル要求キューにあります。それがマージされた後、2.10にバックポートします。 私も、すべてのパターンがうまくいくと言って少し間違っていました。引数の上にかっこを使用する必要があります(パターン2とパターン4) –

答えて

4
2.10の最新の楽園プラグインで

とバニラ2.11で、あなたはそれをこのように行うことができます。

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

私はちょうどMacros.scalaを以下にparadise example projectでそれをテストしてみた:

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"()") 
    } 
} 

Test.scalaを:

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

関数の木の扱いについては、corresponding chapter of quasiquote guideのquasiquotesを参照してください。

関連する問題