我正在尝试将一个小型编译器从 C# 移植到 F#,以利用模式匹配和可区分联合等功能。目前,我正在使用基于 System.Linq.Expressions 的模式对 AST 进行建模:一个抽象基“表达式”类、每个表达式类型的派生类和一个 NodeType 枚举,允许在不进行大量转换的情况下切换表达式。我曾希望使用 F# 有区别的联合来大大减少这种情况,但我遇到了几个看似限制:
- 强制公共默认构造函数(我想对表达式构造进行类型检查和参数验证,就像 System.Linq.Expressions 对它的静态工厂方法所做的那样)
- 缺少命名属性(似乎这在 F# 3.1 中已修复)
- 无法直接引用案例类型。例如,似乎我不能声明一个仅从联合中获取一种类型的函数(例如
let f (x : TYPE) = x
编译为Expression
(联合类型)而不是为Add
orExpression.Add
。这似乎牺牲了我的 C# 方法的一些类型安全性。
这些或设计模式是否有很好的解决方法可以让它们不那么令人沮丧?