【发布时间】:2021-06-23 04:38:40
【问题描述】:
这是关于OCaml中的类型定义,我发现以下语法令人费解:
type 'a t
简单的英语是什么意思?
【问题讨论】:
-
Ocaml Variant Types的可能重复
标签: ocaml
这是关于OCaml中的类型定义,我发现以下语法令人费解:
type 'a t
简单的英语是什么意思?
【问题讨论】:
标签: ocaml
由于 OP 有 C++ 语言的经验,我认为下面的解释可能有用。形式的类型声明:
type 'a t
接近C++
template <typename a> class t;
例如,'a list 是一个通用列表,'a 是一个元素的类型。为简洁起见,我们使用单个 ',而不是 template <typename _> 构造。在 OCaml 的说法中,我们使用术语“参数多态性”,而不是“泛型编程”。我们说的是类型构造函数,而不是单词模板。后者有一个有趣的结果。与在 C++ 中一样,模板实例化创建类型的新实例,在 OCaml 中,协调多态类型的类型变量会创建新类型,例如,int list、float list(c.f.、list<int>、float<list>)。因此,可以将类型构造函数'a list 视为类型级别的一元函数,它接受类型并创建类型。可以有 nary 类型构造函数,例如,type ('key, 'value) hashtbl 是二进制类型构造函数,它为给定的 key 和 value 对创建类型。此外,我们可以将非参数类型视为空类型构造函数,因此int 构造了类型int。
附: F# 语言,OCaml 的后代,允许以两种形式编写:int t 和 t<int>
附言为了防止可能的混淆,我想声明,尽管模板和参数类型试图解决相同的问题,但它们仍然存在一些差异。模板在实例化之后键入,参数类型在之前。所以参数类型 'a t 被定义为 for all 'a。如果你想创建一个类型变量没有被普遍量化的类型,你可以使用另一种机制——函子。它们也非常接近模板,但它们接受类型加类型要求,这是 C++ 术语中的一个概念。这些概念在 OCaml 的模块类型中被具体化,因此函子实际上是模块级别的函数,因为它接受一个模块并产生一个模块。
【讨论】:
这是一个参数类型声明。
类型声明允许您声明新的数据类型:
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 中)
如果它在一个结构中,它声明一个内部没有值的类型。这与空集一样有用(有时有用,但不多)。但是,如果它在签名中,则表示“某处存在参数定义,但从这里看不到”。
假设有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 以及其他定义的函数来操作,但不能直接使用@987654333 @ 和Cons。
【讨论】: