6

ある言語で AST を表す単純なデータ型があるとします。

data Term = Var String
          | Num Integer
          | Expr [Term]

(実際には、明らかにこれよりも多くのコンストラクターがあります。)

これを使用して、AST 構造に一致する単純な評価関数を作成できます。

eval :: Term -> Result
eval (Var name)   = lookup name
eval (Num n)      = return n
eval (Expr exprs) = ...

パターン マッチングの動作を変更せずに、行番号などの情報で AST に注釈を付けることはできますか?

(もちろん、パターンを変更してもかまわないのであれば、レコード構文またはビュー パターンを使用できます。)

4

1 に答える 1

7

AST をポリモーフィックに表現しない理由

data Term term = Var String
      | Num Integer
      | Expr [term]

あなたの元のTermタイプは

newtype SimplTerm = SimplTerm (Term (SimplTerm))

ビューパターンを使用して、必要なことを簡単に行うことができます

data AtLine = AtLine (Term AtLine) Integer

view :: AtLine -> Term AtLine
view (AtLine x _) = x

eval (view -> Var name) = lookup name
eval (view -> Num n) = numResult n
eval (view -> Expr expr) = listResult (map eval expr)

またはビューをポリモーフィックにする

class AST t where
   term :: t -> Term t
instance AST SimplTemr where
   term (SimplTemr x) = x
instance AST AtLine where
   term (AtLine x _) = x

eval :: AST t => t -> Result
eval (view -> Var name) = lookup name
eval (view -> Num n) = numResult n
eval (view -> Expr expr) = listResult (map eval expr)

エラー処理のために、ビューパターンをモナドに表示する方法があればいいのにと思いますが、それは人生です(view関数がcpsで実行され、値を返すのではなく継続を引数として取る場合に可能です)。

于 2013-04-25T02:29:10.357 に答える