问题
I want to substitute a specific AST node into another, and this substituted node is specified by interactive user input.
In non-functional programming, you can use mutable data structure, and each AST node have a object reference, so when I need to reference to a specific node, I can use this reference.
But in functional programming, use IORef
is not recommended, so I need to generate id for each AST node, and I want this id to be stable, which means:
- when a node is not changed, the generated id will also not change.
- when a child node is changed, it's parent's id will not change.
And, to make it clear that it is an id instead of a hash value:
- for two different sub nodes, which are compared equal, but corresponding to different part of an expression, they should have different id.
So, what should I do to approach this?
回答1:
Perhaps you could use the path from the root to the node as the id of that node. For example, for the datatype
data AST = Lit Int
| Add AST AST
| Neg AST
You could have something like
data ASTPathPiece = AddGoLeft
| AddGoRight
| NegGoDown
type ASTPath = [ASTPathPiece]
This satisfies conditions 2 and 3 but, alas, it doesn't satisfy 1 in general. The index into a list will change if you insert a node in a previous position, for example.
If you are rendering the AST into another format, perhaps you could add hidden attributes in the result nodes that identified which ASTPathPiece
led to them. Traversing the result nodes upwards to the root would let you reconstruct the ASTPath
.
来源:https://stackoverflow.com/questions/50960866/how-to-generate-stable-id-for-ast-nodes-in-functional-programming