(マクロ) コンテキストの resetLocalAttrs メソッドを使用するマクロをコーディングしました。マクロが展開された後、奇妙なエラーが発生し、何が起こっているのかわかりません。まず、問題を紹介します。state (単純な Int として表します) とactionの 2 つのプリミティブがあります。状態はシステムの現在の状態を表し、アクションは状態の変更を担当します。アクションは、アトミックにすることも、アトミック アクションで構成することもできます。
trait Action {
def andNext(action: PartialFunction[Int, Int => Action]): AndNext = AndNext(this, action)
}
case class ActionId extends Action
case class AndNext(action: Action, and: PartialFunction[Int, Int => Action]) extends Action
コードでわかるように、AndNextは部分関数を受け取ります。これは、その瞬間の現在の状態に応じて、1 つまたは別のアクションを起動できるためです。構成されたアクション内にあるアトミック アクションは、シーケンス内の先行するアトミック アクションによって残された先行状態を必要とする可能性があるため、Int => Actionで保護する必要があります。
ダミー関数を使用してテストにInt => Actionパラメーターを強制的に要求させて、コードをテストしてみましょう。
def f(lifted: Int => Action) = ???
f(implicit state => ActionId() andNext { case _ => implicit state => ActionId() })
大丈夫ですが、私は DSL に取り組んでおり、冗長な暗黙の状態をすべて記述するには冗長すぎます。このコードを DSL の使用に適したものにするために、それらを非表示にする必要があります。次のかわいい呼び出しに到達しようとしています...
f(ActionId() andNext { case _ => ActionId() })
アクションを保護されたアクションに変換するマクロを実装しました (Int => Action を思い出してください)。
implicit def lift[T](expr: T): Int => T = macro liftImpl[T]
def liftImpl[T: c.WeakTypeTag](c: Context)(expr: c.Expr[T]): c.Expr[Int => T] = {
import c.mirror._
import c.universe._
//reify(implicit state => expr.splice)
reify(implicit state => c.Expr[T](c.resetLocalAttrs(expr.tree)).splice)
}
(*)ビュー内のメソッドを変換するマクロ宣言の暗黙に注意してください。
前者 (およびコメント付き) の reify は問題なく動作しますが、いくつかの制限があるため、resetLocalAttrs() を呼び出す reifyを使用する必要があります (知りたくない場合は、この質問が長すぎます :)。この具体化は奇妙なエラーで失敗します:
class Any is abstract; cannot be instantiated
どこで Any をインスタンス化しようとしていますか? リセットが AST に大きな影響を与えるのはなぜですか? 私はそれを何度も使用しましたが、タイプとシンボルをうまくリセットしていました。
問題を見つけるためのより良いアプローチは何ですか? 私は showRaw を使用してtypeとidsフラグを有効にしてきましたが、かなり難しくなっています。