“使用”可以做什么;“约束”;OCaml中的关键字

“使用”可以做什么;“约束”;OCaml中的关键字,ocaml,typing,parametric-polymorphism,Ocaml,Typing,Parametric Polymorphism,描述可在类型定义中使用的“constraint”关键字。然而,我无法找出任何可以使用这个关键字的用法。这个关键字什么时候有用?它可以用来删除多态类型变量吗?(这样模块中的type'a t就变成了t,该模块可以用于要求t不带变量的函子参数。)因此,类型或类定义中使用的约束关键字可以说,将适用类型的“范围”缩小为一个类型参数。文档清楚地宣布,来自约束方程两侧的类型表达式将被统一,以“细化”约束相关的类型。因为它们是类型表达式,所以可以使用所有常用的类型级别运算符 示例: # type 'a t =

描述可在类型定义中使用的“constraint”关键字。然而,我无法找出任何可以使用这个关键字的用法。这个关键字什么时候有用?它可以用来删除多态类型变量吗?(这样模块中的
type'a t
就变成了
t
,该模块可以用于要求
t
不带变量的函子参数。)

因此,类型或类定义中使用的
约束
关键字可以说,将适用类型的“范围”缩小为一个类型参数。文档清楚地宣布,来自约束方程两侧的类型表达式将被统一,以“细化”约束相关的类型。因为它们是类型表达式,所以可以使用所有常用的类型级别运算符

示例:

# type 'a t = int * 'a constraint 'a * int = float * int;;
type 'a t = int * 'a constraint 'a = float

# type ('a,'b) t = 'c r constraint 'c = 'a * 'b
    and 'a r = {v1 : 'a; v2 : int };;
type ('a,'b) t = ('a * 'b) r
and 'a r = { v1 : 'a; v2 : int; }
观察类型统一是如何简化方程的,在第一个示例中,通过去掉无关的类型积(
*int
),在第二个示例中,完全消除它。还要注意,我使用了一个类型变量
'c
,它只出现在类型定义的右侧

两个有趣的用途是多态变量和类类型,它们都基于行多态性。约束允许表达某些子类型关系。通过子类型,对于变体,我们指的是这样一种关系,即类型的任何构造函数都存在于其子类型中。其中一些关系可能已经用单态表示:

# type sum_op = [ `add | `subtract ];;
type sum_op = [ `add | `subtract ]
# type prod_op = [ `mul | `div ];;
type prod_op = [ `mul | `div ]
# type op = [ sum_op | prod_op ];;
type op = [ `add | `div | `mul | `sub ]
其中,
op
sum\u op
prod\u op
的子类型

但在某些情况下,您必须引入多态性,这就是约束便利的地方:

# type 'a t = 'a constraint [> op ] = 'a;;
type 'a t = 'a constraint 'a = [> op ]
上面让您表示属于
op
子类型的类型族:对于
'at
的给定实例,类型实例本身就是
'a

如果我们试图在没有参数的情况下定义相同的类型,则类型统一算法将抱怨:

# type t' = [> op];;
Error: A type variable is unbound in this type declaration.
In type [> op ] as 'a the variable 'a is unbound
相同种类的约束可以用类类型表示,如果类型定义通过子类型隐式多态,则可能会出现相同的问题

# class type ct = object method v : int end;;
class type ct =  object method v : int end
# type i = #ct;;
Error: A type variable is unbound in this type declaration.
In type #ct as 'a the variable 'a is unbound
# type 'a i = 'a constraint 'a = #ct;;
type 'a i = 'a constraint 'a = #ct

没有时间写点东西,但你可能会发现利奥·怀特最近对行多态性的回应很有帮助。上一个问题中给出了一个例子。您也可以将其用于多态变体。谢谢您的回答。我对ocaml类不是很熟悉。你有没有不涉及他们的例子?谢谢你给出了非常清晰的答案。我觉得很不舒服,因为您给出的用法似乎只修复了原始类型系统中的一个弱点。我知道我可能错了,但我不明白为什么不使用“constraint”关键字就不能直接定义“opentype”。毕竟,编译器在使用默认大小写键入匹配项时使用此类型。您所说的开放类型是什么意思?你是指类接口的
#
符号吗?我的观点是,原始的类型系统,允许用
类型…
符号定义新类型,没有处理子类型。这来自于对象语言出现之前可用的类型构造函数集,但是随着新语言的出现,需要一种方法来简化两种类型语言。因此,可能会有一种轻微的“被拴住”的感觉。我不知道如果不是这样的话怎么会这样。好的,谢谢。我不想写“开放类型”,而是写“开放联合”,这是我在某处读到的[>…]符号的一个术语。这个答案似乎颠倒了多态变体的子类型关系
sum_op
prod_op
op
的子类型,而不是相反,
[>op]
指的是
op
的超类型,而不是子类型。如果变量类型支持较少的构造函数,则它是另一个(宽度)子类型(可以在需要另一个的地方使用)。