OCaml 语法:type 'a t 是什么意思?

OCaml syntax: what does type 'a t mean?

这是关于 OCaml 中的类型定义,我发现以下语法令人费解:

type 'a t

简单的英语是什么意思?

这是参数类型声明。

类型声明允许您声明新的数据类型:

type my_type = int * string

let x : my_type = (42,"Sorry for the inconvenience")

然而,有时您希望一个类型是参数化的,这意味着它采用另一种类型作为参数:

type 'a container = 'a * string * 'a

let x : int container = (0, "hello", 1)
let y : string container = ("stack", "over", "flow")

现在在那种情况下,在你的类型声明之后没有相等的。其含义取决于它是在模块的 structure 中(例如,在 .ml 文件之上)还是在 signature 中(例如在 .mli 中)

如果在结构中,它声明了一个内部没有值的类型。这和空集一样有用(有时是,但不多)。但是,如果它在签名中,则表示 "there exists a parametric definition somewhere, but it is not visible from here".

假设有这两个文件 a.mla.mli:

(* a.ml *)
type 'a t = Nil | Cons of 'a * 'a t

let empty = Nil
let add x l = Cons (x,l)

(* and so on... *)

(* a.mli *)

type 'a t

val empty : 'a t
val add : 'a -> 'a t -> 'at

(* and so on... *)

如果在你的程序的其余部分你想操作 A.t 类型,你将只能通过 emptyadd 以及其他定义的函数来实现, 但不是通过直接使用 NilCons.

既然OP有C++语言的经验,我想下面的解释可能会有用。形式的类型声明:

type 'a t

接近于 C++

template <typename a> class t;

例如,'a list是一个泛型列表,'a是一个元素的类型。为简洁起见,我们使用单个 ',而不是 template <typename _> 结构。在 OCaml 中,我们使用术语“参数多态性”,而不是“泛型编程”。我们说的不是单词模板,而是类型构造函数。后者有一个有趣的结果。与 C++ 中的模板实例化创建类型的新实例一样,在 OCaml 中,协调多态类型的类型变量创建新类型,例如 int listfloat list (c.f., list<int>, float<list>).因此,可以将类型构造函数 'a list 视为类型级别的一元函数,它接受一个类型,并创建一个类型。可以有 nary 类型构造函数,例如,type ('key, 'value) hashtbl 是一个二进制类型构造函数,它为给定的 keyvalue 对创建一个类型。此外,我们可以将非参数类型视为空类型构造函数,因此 int 构造类型 int.

P.S。 F# 语言是 OCaml 的后代,允许以两种形式编写:int tt<int>

P.P.S。为了防止可能出现的混淆,我想说明一下,尽管模板和参数类型试图解决相同的问题,但它们仍然存在一些差异。模板在实例化之后键入,参数类型在实例化之前键入。所以参数类型 'a t 被定义为 for all 'a。如果你想创建一个类型变量没有被普遍量化的类型,你可以使用另一种机制——函子。它们也非常接近模板,但它们接受类型加类型要求,这是 C++ 术语中的一个概念。这些概念在 OCaml 的模块类型中具体化,因此仿函数实际上是模块级别的函数,因为它接受模块并生成模块。