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

5
这篇文章涉及到OCaml中的类型定义,我发现以下语法让人感到困惑:

type 'a t

用通俗易懂的语言来解释是什么意思?


可能是 Ocaml 变体类型 的重复问题。 - Laurel
2个回答

7

由于OP有C++语言的经验,我认为以下解释可能会有用。形式为:

type 'a t

与C++接近

template <typename a> class t;

例如,'a list 是一个通用列表,'a 是元素的类型。为了简洁起见,我们使用单个 ',而不是 template <typename _> 构造。在 OCaml 中,我们使用术语“参数多态性”,而不是“通用编程”。而且,我们说类型构造器而不是模板。后者有一个有趣的结果。就像在 C++ 中,模板实例化创建类型的新实例一样,在 OCaml 中,将多态类型的类型变量具体化会创建一个新类型,例如 int listfloat list(与 list<int>float<list> 相比)。因此,可以将类型构造器 'a list 视为类型级别上的一元函数,它接受一种类型并创建一种类型。可能存在多元类型构造器,例如 type ('key, 'value) hashtbl 是一个二元类型构造器,它为给定的 keyvalue 对创建一种类型。此外,我们可以将非参数类型视为零元类型构造器,因此 int 构造类型 int

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

P.P.S. 为了防止可能的混淆,我想声明,虽然模板和参数类型试图解决相同的问题,但它们仍然有一些区别。模板在实例化后进行类型化,而参数类型在之前进行类型化。因此,参数类型 'a t 被定义为对于所有的 'a。如果要创建一个类型,其中类型变量没有普遍量化,可以使用另一种机制 - 函数子。它们也非常接近模板,但它们接受类型加上类型要求,这是 C++ 中的概念。概念在 OCaml 的模块类型中具体化,因此函数子实际上是模块级别上的函数,因为它接受一个模块并生成一个模块。


6

这是一个参数化类型声明。

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

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")

在这种情况下,您的类型声明后面没有等号。这取决于它是在模块的结构中(比如在一个 .ml 文件的顶部),还是在签名中(例如,在一个 .mli 文件中)。如果它在结构中,它声明了一个没有值的类型。这就像一个空集合一样有用(有时候是有用的,但不多)。但是,如果它在签名中,它的意思是“存在一个参数化定义,但在这里看不到”。假设有这两个文件 a.ml 和 a.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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接