I'm writing the data structures for my program (a toy compiler), and I'm trying to understand what's the best way to define the AST:
Current code
data RExpr = RExpr Location InnerRExpr
data InnerRExpr = RLExpr LExpr | RConstant Constant | RMathExpr MathExpr | FCall Id [RExpr]
Alternative A
data RExpr = RLExpr Location LExpr
| RConstant Location Constant
| RMathExpr Location MathExpr
| FCall Location Id [RExpr]
Alternative B
data RExpr = RLExpr { loc::Location, getLexpr::LExpr}
| RConstant { loc::Location, getConstant::Constant}
| RMathExpr { loc::Location, getExpr::MathExpr}
| FCall { loc::Location, id::Id, params::[RExpr] }
Honestly I'm not satisfied with either of the three options, because the current code means that I have an extraneous object in the AST which doesn't really mean anything, alternative A means that I have to pattern match every time I want to extract the location (or write a boilerplate function that does it) and alternative B means cluttering the global namespace with functions whose names are likely to collide.
Suggestions?