Generics 此构造导致代码不太通用。。。当应用于幻影类型时
我正在尝试用F#实现一种小型语言的DSL。不幸的是,当我试图约束节点以保存额外的类型信息(通过幻象类型)时,编译器会阻止我 以下代码行说明了该问题:Generics 此构造导致代码不太通用。。。当应用于幻影类型时,generics,f#,Generics,F#,我正在尝试用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(
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)
type Expr)=
匹配表达式
|Int(n)->字符串n
|等式(x,y)->sprintf“%s==%s”(到字符串x)(到字符串y)
|非(b)->sprintf“!%s”(到字符串b)
根据编译器,构造到字符串x
发出以下警告:
构造导致代码不像类型注释所指示的那样通用。类型变量“a”已被约束为类型“int”
接下来,在下一行,构造到字符串b
发出此错误:
类型不匹配。应为Expr
但给定Expr
类型int
与类型bool
我似乎找不到任何方法来规避这种行为,事实上,我也找不到导致这段代码没有我预期的那么通用的原因。如果可能的话,我更喜欢不完全放弃幻影类型的解决方案
我是不是做错了什么?这可能是编译器错误吗?您需要将
to_string
函数设置为通用函数:
let rec to_string<'a> (expr:Expr<'a>) : string =
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)
Not (Eq (Int 1, Int 2))
|> to_string