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

5 ocaml

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

type 'a t
Run Code Online (Sandbox Code Playgroud)

简单的英语是什么意思?

Pat*_*atJ 6

这是一个参数类型声明.

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

type my_type = int * string

let x : my_type = (42,"Sorry for the inconvenience")
Run Code Online (Sandbox Code Playgroud)

但有时,您希望类型是参数化的,这意味着它需要另一种类型作为参数:

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

let x : int container = (0, "hello", 1)
let y : string container = ("stack", "over", "flow")
Run Code Online (Sandbox Code Playgroud)

现在,在这种情况下,你的类型声明后就没有了.其含义取决于它是否在模块中structure(例如,在.ml文件顶部)或在signature(例如在a中.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... *)
Run Code Online (Sandbox Code Playgroud)

如果在你的程序的其余部分要处理的A.t类型,你就可以只通过这样做empty,并add和其他定义的函数,而不是通过直接使用NilCons.


ivg*_*ivg 5

由于OP具有C++语言的经验,我认为以下解释可能有用.表格的类型声明:

type 'a t
Run Code Online (Sandbox Code Playgroud)

接近C++

template <typename a> class t;
Run Code Online (Sandbox Code Playgroud)

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

PS F#语言是OCaml的后代,允许以两种形式书写:int tt<int>

PPS为了防止可能的混淆,我想说,虽然模板和参数类型试图解决相同的问题,但它们仍然没有什么区别.模板在实例化后输入,之前是参数类型.所以参数类型'a t为所有人 定义'a.如果要创建一个类型变量未被普遍量化的类型,可以使用其他机制 - 仿函数.它们也非常接近模板,但它们接受类型加类型要求,这是C++用语中的概念.这些概念在OCaml中的模块类型中有所体现,因此仿函数实际上是模块级别的函数,因为它接受模块并生成模块.