Ocaml 多态变体和类型签名

Ocaml 多态变体和类型签名,ocaml,polymorphic-variants,Ocaml,Polymorphic Variants,(这是对的扩展/升华) 考虑以下代码: 第1版: 让x:[>`Error1]=(`Error1:[>`Error1]) 设y:[>`Error1 |`Error2]=x 第2版: 让x:[>`Error1]=(`Error1:[`Error1]) 设y:[>`Error1 |`Error2]=x 版本1进行类型检查,但版本2失败(我使用4.09.0进行编译): 请注意,此错误发生在y的定义中,但x的签名在这两种情况下是相同的!在x的定义中,y是如何看到的?关于x的类型检查信息是否比其签名多?

(这是对的扩展/升华)

考虑以下代码:

第1版:

让x:[>`Error1]=(`Error1:[>`Error1])
设y:[>`Error1 |`Error2]=x
第2版:

让x:[>`Error1]=(`Error1:[`Error1])
设y:[>`Error1 |`Error2]=x
版本1进行类型检查,但版本2失败(我使用4.09.0进行编译):


请注意,此错误发生在
y
的定义中,但
x
的签名在这两种情况下是相同的!在
x
的定义中,
y
是如何看到的?关于
x
的类型检查信息是否比其签名多?

简而言之,显式类型注释不是类型签名。 特别是

让x:[>`Error1]=(`Error1:[`Error1])
x
的类型是
[`Error1]

问题的根源在于显式类型注释中的统一类型变量可以与具体类型统一

你的问题的一个简单例子是

让f:'a->'a=fun x->x+1
这里,
'a->'a
注释与实类型
int->int
统一,因此该代码类型检查。如果要使类型变量
'a
通用,则需要通过添加显式通用量化使其更显式

让f'a.'a->'a=funx->x+1
错误:此定义的int->int类型比
“a.”a->‘a’
使用隐式行变量的代码也会出现同样的现象:

让x:[>`Error1]=(`Error1:[`Error1])
此注释不保证
x
的类型为
[>`Error1]
,但仅保证它可以与
[>`Error1]
统一。由于类型
[`Error1]
可以与
[>`Error1]
统一,因此没有理由提出错误

如前所述,如果要避免此问题,需要明确说明注释中哪些变量是通用量化的:

让x:'行。([>`Error1]as'行)=(`Error1:[`Error1])
Error:此表达式的类型为[`Error1]
但应为[>`Error1]类型的表达式
第二个变量类型绑定到通用类型变量'a,
它不能关闭

简而言之,显式类型注释不是类型签名。 特别是

让x:[>`Error1]=(`Error1:[`Error1])
x
的类型是
[`Error1]

问题的根源在于显式类型注释中的统一类型变量可以与具体类型统一

你的问题的一个简单例子是

让f:'a->'a=fun x->x+1
这里,
'a->'a
注释与实类型
int->int
统一,因此该代码类型检查。如果要使类型变量
'a
通用,则需要通过添加显式通用量化使其更显式

让f'a.'a->'a=funx->x+1
错误:此定义的int->int类型比
“a.”a->‘a’
使用隐式行变量的代码也会出现同样的现象:

让x:[>`Error1]=(`Error1:[`Error1])
此注释不保证
x
的类型为
[>`Error1]
,但仅保证它可以与
[>`Error1]
统一。由于类型
[`Error1]
可以与
[>`Error1]
统一,因此没有理由提出错误

如前所述,如果要避免此问题,需要明确说明注释中哪些变量是通用量化的:

让x:'行。([>`Error1]as'行)=(`Error1:[`Error1])
Error:此表达式的类型为[`Error1]
但应为[>`Error1]类型的表达式
第二个变量类型绑定到通用类型变量'a,
它不能关闭
File "test.ml", line 2, characters 33-34:
2 | let y : [> `Error1 | `Error2 ] = x
                                     ^
Error: This expression has type [ `Error1 ]
       but an expression was expected of type [> `Error1 | `Error2 ]
       The first variant type does not allow tag(s) `Error2