5

マクロを使用しているときに、特定の条件を保持する AST 内のノードを更新する必要があるポイントに到達しました (回避しようと懸命に努力してきました)。たとえば、各ノードを更新したいとします。

Literal(Constant(1))

値で:

Literal(Constant(2))

これらの AST ノードは式ツリーのどこにでもある可能性があるため、アドホック パターン マッチャーは使用できません。明らかに、私が最後にやりたいことは、すべてのコンパイラ プリミティブをカバーできる完全なパターン マッチャーをコーディングすることです。私はAPIを検索してきましたが、 collecttraversableファミリーなどのメソッドは、ツリーを線形のものとして扱うため、私のニーズを満たすのに十分ではないという印象を受けました。結果として、更新されたツリー全体が必要です。 . では、不変の式ツリーをスマートな方法で更新することは可能でしょうか? 標準 API にそのような「更新」操作が存在しないのはなぜですか?

4

2 に答える 2

3

Scala マクロで AST トランスフォーマーを使用する例を次に示します。

https://github.com/retronym/macrocosm/blob/171be7e/src/main/scala/com/github/retronym/macrocosm/Macrocosm.scala#L129

于 2012-07-09T18:57:14.507 に答える
2

データ構造の poly-typed ノードをジェネリックに変更することは、データ型ジェネリック (型コンストラクターによるコードのパラメーター化) の典型的なケースです。

このような操作には、データ型のジェネリック トラバーサル関数を定義する「Scrap Your Boilerplate」アプローチなど、いくつかのアプローチが存在します。

Haskell では、ノード更新関数は、データ型とコードの 2 つの次元でパラメーター化されているため、構造内の任意の場所で、さまざまな更新関数をさまざまな型に適用できます。

-- | Apply a transformation everywhere in bottom-up manner
everywhere :: (forall a. Data a => a -> a)
           -> (forall a. Data a => a -> a)

Haskell でこれを行うには、型クラスに大きく依存します。Scala には、移植された例がいくつかあります。

于 2012-07-09T15:19:30.093 に答える