这是关于OCaml中的类型定义,我发现以下语法令人费解:
type 'a t
简单的英语是什么意思?
答案 0 :(得分:6)
这是一个参数类型声明。
类型声明允许您声明一个新的数据类型:
rw_mutex
但有时候,您希望类型是参数化的,这意味着它需要另一种类型作为参数:
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
中)< / p>
如果它在结构中,则声明一个内部没有值的类型。哪个像空集一样有用(有时它是,但不多)。但是,如果它在签名中,则表示“某处存在参数化定义,但从此处不可见”。
假设有两个文件.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
和empty
以及其他已定义的函数执行此操作,但而不是直接使用add
和Nil
。
答案 1 :(得分:5)
由于OP具有C ++语言的经验,我认为以下解释可能有用。表格的类型声明:
type 'a t
接近C ++
template <typename a> class t;
例如,'a list
是通用列表,'a
是元素的类型。为简明起见,我们使用单个'
而不是template <typename _>
构造。在OCaml的说法中,我们使用术语“参数多态”,而不是“泛型编程”。而不是单词模板,我们说一个类型构造函数。后者有一个有趣的结果。与在C ++中一样,模板实例化创建类型的新实例,在OCaml中,协调多态类型的类型变量会创建新类型,例如int list
,float list
(cf,list<int>
, float<list>
)。因此,可以将类型构造函数'a list
视为类型级别上的一元函数,它接受一个类型,并创建一个类型。可以使用nary类型构造函数,例如type ('key, 'value) hashtbl
是二进制类型构造函数,它为给定的key
和value
对创建类型。此外,我们可以将非参数类型视为一个nullary类型构造函数,因此int
构造类型int
。
P.S。 F#语言是OCaml的后代,允许以两种形式书写:int t
和t<int>
P.P.S。为了防止可能的混淆,我想说,尽管模板和参数类型试图解决相同的问题,但它们仍然没有什么区别。模板在实例化后输入,之前是参数类型。因此,为所有 'a t
定义参数类型'a
。如果要创建一个类型变量未被普遍量化的类型,可以使用其他机制 - 仿函数。它们也非常接近模板,但它们接受类型加类型要求,这是C ++用语中的概念。这些概念在OCaml中的模块类型中有所体现,因此仿函数实际上是模块级别的函数,因为它接受模块并生成模块。