我正在尝试在F#中实现一个用于小语言的DSL.不幸的是,当我试图约束节点来保存其他类型信息时(通过幻像类型),编译器阻止了我的追踪.
以下代码行说明了这个问题:
type Expr<'a> =
| Int of int
| Eq of Expr<int> * Expr<int>
| Not of Expr<bool>
let rec to_string (expr: Expr<'a>) =
match expr with
| Int(n) -> string n
| Eq(x, y) -> sprintf "%s == %s" (to_string x) (to_string y)
| Not(b) -> sprintf "!%s" (to_string b)
Run Code Online (Sandbox Code Playgroud)
根据编译器,构造to_string x发出以下警告:
构造使代码比类型注释所指示的更不通用.类型变量'a已被约束为类型'int'.
接下来,在下一行,构造to_string b发出此错误:
类型不匹配.期待
Expr<int>但是给定Expr<bool>的类型int与类型不匹配bool
我似乎无法找到任何方法来规避这种行为,事实上我找不到这个代码比我预期的更不通用的原因.如果可能的话,我宁愿选择一种不完全放弃幻像类型的解决方案.
我做了一些根本错误的事吗?这可能是编译器错误吗?