Answer the question
In order to leave comments, you need to log in
Is there a simple and elegant way to add position information to a syntactic tree with mutually recursive types?
There is a syntax tree with mutually recursive types LVal and Expr:
data Expr = IntLit Int
| StrLit String
| LVal LVal
| Binop Expr Binop Expr
| Assign LVal Expr
data Binop = Add | Sub | Mul | Div
data LVal = Var String
| Dot LVal String
| Index LVal Expr
data Expr = IntLit Int Position
| StrLit String Position
| LVal LVal Position
| Binop Expr Binop Expr Position
| Assign LVal Expr Position
data Binop = Add | Sub | Mul | Div
data LVal = Var String Position
| Dot LVal String Position
| Index LVal Expr Position
newtype Fix2 f g = Fix2 { unFix2 :: f (Fix2 f g) (Fix2 g f) }
data Expr = IntLit Int
| StrLit String
| LVal LVal
| Binop Expr Binop Expr
| Assign LVal Expr
| EAnn Expr Position
data Binop = Add | Sub | Mul | Div
data LVal = Var String
| Dot LVal String
| Index LVal Expr
| LAnn LVal Position
Answer the question
In order to leave comments, you need to log in
For working with AST, functor encodings are more preferable precisely due to the ability to uniformly slip new features into everyone (and then throw them off at once). And it’s more pleasant to work with ready-made recursion schemes than to open a bicycle factory.
I sketched an example with adding annotations to these expressions: https://repl.it/@ICRainbow/RoundHuskyExabyte
Fix2 is not needed, but you need to clearly understand what the functor and the fixed point will be in which expressions. It's not difficult, but it takes practice.
There seems to be no such way.
And why the second option is inconvenient?
See, for example, haskell-src-exts , where each type has an extra. an element of type l, which may have a position or something else.
In ghc, it is done similarly , but a little differently - some constructors are wrapped in Located
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question