为什么不以多态方式表示 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)
对于错误处理,我希望有一种方法可以让视图模式出现在 monad 中,但这就是生命(如果view
函数在 cps 中完成,你可以这样做,因此将延续作为参数而不是返回值)。