Why not imagine AST polymorphically
data Term term = Var String | Num Integer | Expr [term]
then your type is orignal Term
newtype SimplTerm = SimplTerm (Term (SimplTerm))
and you can easily do what you want with viewing templates
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)
or make it look polymorphic
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)
for error handling. I would like for presentation templates to appear in the monad, but this is life (what could you do if the view function was executed in cps and therefore took continuation as an argument, rather than returning a value).
source share