Digamos que estoy construyendo un analizador para un lenguaje específico de dominio en F #.F # patrón de diseño
he definido una unión discriminada para representar expresiones:
type Expression =
| Equality of Expression*Expression
| NonEquality of Expression*Expression
| Or of Expression*Expression
| And of Expression*Expression
| If of Expression*Expression
| IfElse of Expression*Expression*Expression
| Bool of bool
| Variable of string
| StringLiteral of string
Ahora, yo he construido un AST de tipo Expression
y desea generar código para ello. Tengo una función que escribe inferencia y comprueba el tipo en una expresión.
Se define como
let rec InferType expr =
match expr with
| Equality(e1,e2) -> CheckTypes (InferType e1) (InferType e2)
| Or(e1,e2) -> CheckTypes (InferType e1) (InferType e2)
| And(e1,e2) -> CheckTypes (InferType e1) (InferType e2)
...
Y tengo otra función para generar código que sigue un patrón similar: Tomar una expresión, escribir declaraciones de patrones de coincidencia para cada elemento de la unión.
Mi pregunta es: ¿Es esta la manera idiomática de hacerlo en F #?
Me parece que sería más limpio si cada miembro de la unión definiera su propio InferType
y GenerateCode
localmente con él.
Si estuviera usando C#, definiría una clase base abstracta llamada Expression
con métodos virtuales para InferType
y GenerateCode
y luego los anularía en cada subclase.
¿Hay alguna otra manera de hacerlo?
Gracias - Esta fue la respuesta que estaba buscando . –