2

Scalaマクロでパラメーター値にアクセスするときのコンパイルの問題に続いて、述語を適用するマクロを定義したいと思います。ステートメント fn = c.eval( pred ) が存在する場合、クライアント コードはコンパイルに失敗し、問題の性質については何も示されません。

def fnInvocation( value : Int, pred : c.Expr[ Int => Boolean ] ): Boolean = fnInvocationImpl

def fnInvocationImpl(c: Context)( value : Int, pred : c.Expr[ Int => Boolean ] ) : c.Expr[Boolean] = {
    var fn = x => x % 2 == 0
    //    fn = c.eval( pred ) // client compilation fails if this line is included
    val result = fn( value )
    c.literal( result )
}

マクロ内からこれを実行できるようにする必要がありますか?

4

1 に答える 1

1

マクロ メソッド自体には初期コンテキスト パラメーター リストがなく、式の引数を持つ意味がありません。一方、それらの実装では、すべての引数 (コンテキストを含む初期パラメーター リストの後の)は式でなければなりません

あなたの場合、署名は次のようにする必要があります。

def fnInvocation(value: Int, pred: Int => Boolean): Boolean =
  macro fnInvocationImpl

def fnInvocationImpl(c: Context)(
  value: c.Expr[Int],
  pred: c.Expr[Int => Boolean]
): c.Expr[Boolean] = ???

私の以前の回答のコメントはここにも当てはまります。両方の引数がコンパイル時のリテラルである場合は、コンパイル時にアプリケーションを実行できます。この種のことが関数リテラルでどのように機能するかの例については、私の要旨を参照してください。どちらもリテラルでない場合は、実行時にアプリケーションを実行するツリーを構築できます。引数が両方ともリテラルであるかどうかをチェックし、関数を適用して、そうであればコンパイル時のリテラルを返し、それ以外の場合はツリーの生成にフォールバックすることもできます。できないことは、値がリテラルでない場合、コンパイル時にアプリケーションを実行することです。

于 2013-08-31T11:15:42.517 に答える