Types OCaml中的多态递归对象类型

Types OCaml中的多态递归对象类型,types,ocaml,Types,Ocaml,为什么在OCaml中不可能做到这一点: type 'a cl = < f : 'b . 'b -> 'b cl >;; 那么,一般来说,是不可能有这样的对象,还是遗漏了一些特殊的语法?这条(令人惊讶的特定)消息意味着什么?在Ocaml中有两种形式的递归类型: 结构递归类型(也称为等递归)。当您仅仅定义一个类型同义词时,就会出现这种情况,就像您的例子一样。对于这些类型,递归必须是统一的,这意味着所有递归出现必须使用与左侧完全相同的参数。(您试图使方法多态的事实实际上与此无关。

为什么在OCaml中不可能做到这一点:

type 'a cl = < f : 'b . 'b -> 'b cl >;;

那么,一般来说,是不可能有这样的对象,还是遗漏了一些特殊的语法?这条(令人惊讶的特定)消息意味着什么?

在Ocaml中有两种形式的递归类型:

  • 结构递归类型(也称为等递归)。当您仅仅定义一个类型同义词时,就会出现这种情况,就像您的例子一样。对于这些类型,递归必须是统一的,这意味着所有递归出现必须使用与左侧完全相同的参数。(您试图使方法多态的事实实际上与此无关。)

  • 标称递归类型(也称为iso递归)。这些由具有数据构造函数的类型声明产生。在这种情况下,递归应用程序是不受限制的。例如:

    type 'a t = C of 'a list t
    
在第一种情况下限制的原因是结构类型定义总是被它们的定义(至少在概念上)替换。如果递归不是一致的,那么这种展开可能是无限大的(从技术上讲,这样的定义将描述不再是规则树的类型)

在名义上的情况下,这个问题不会出现,因为它们定义了新类型,而新类型的定义永远不会隐式展开。要付出的代价是,您必须通过应用或匹配这些类型的一个数据构造函数,显式地“强制”(更准确地说,是注入和投射)这些类型

编辑:因此,您可以尝试将您的类型定义为数据类型:

type 'a cl = Cl of <f : 'b. 'b -> 'b cl>
type'a cl=cl'b cl>
然而,使用它显然有点冗长,因为您必须管理
Cl
构造函数

type 'a cl = Cl of <f : 'b. 'b -> 'b cl>