第 12 章 语言扩展

4 局部抽象类型

(在 OCaml 3.12 中引入,在 4.03 中添加了简写语法)

参数::= ...
 (type { typeconstr-name }+)

表达式 fun ( type typeconstr-name ) -> expr 引入了一个名为 typeconstr-name 的类型构造器,在子表达式的范围内被认为是抽象的,但随后会被一个新的类型变量替换。请注意,与语法可能暗示的相反,表达式 fun ( type typeconstr-name ) -> expr 本身不会像常规抽象那样挂起 expr 的求值。语法已被选择以很好地适应函数声明的上下文,它通常在其中使用。可以自由地混合常规函数参数和伪类型参数,如

let f = fun (type t) (foo : t list) -> …

甚至可以使用声明函数的替代语法

let f (type t) (foo : t list) = …

如果需要引入多个局部抽象类型,可以使用语法 fun ( type typeconstr-name1typeconstr-namen ) -> expr 作为 fun ( type typeconstr-name1 ) ->-> fun ( type typeconstr-namen ) -> expr 的语法糖。例如,

let f = fun (type t u v) -> fun (foo : (t * u * v) list) -> … let f' (type t u v) (foo : (t * u * v) list) = …

这种结构很有用,因为它引入的类型构造器可以在不允许使用类型变量的地方使用。例如,可以使用它在一个多态函数内的局部模块中定义异常。

let f (type t) () = let module M = struct exception E of t end in (fun x -> M.E x), (function M.E x -> Some x | _ -> None)

这是另一个例子

let sort_uniq (type s) (cmp : s -> s -> int) = let module S = Set.Make(struct type t = s let compare = cmp end) in fun l -> S.elements (List.fold_right S.add l S.empty)

它对于一等模块(参见第 12.5 节)和广义代数数据类型(GADTs:参见第 12.10 节)也极其有用。

多态语法

(在 OCaml 4.00 中引入)

let 绑定::= ...
 value-name:type { typeconstr-name }+.typexpr=expr
 
类字段::= ...
 method [private] method-name:type { typeconstr-name }+.typexpr=expr
 method! [private] method-name:type { typeconstr-name }+.typexpr=expr

(type typeconstr-name) 语法结构本身不会使它引入的类型变量多态化,但可以在需要时与显式多态注释结合使用。以上规则作为语法糖提供,使其更容易

let rec f : type t1 t2. t1 * t2 list -> t1 = …

自动扩展为

let rec f : 't1 't2. 't1 * 't2 list -> 't1 = fun (type t1) (type t2) -> ( … : t1 * t2 list -> t1)

当定义涉及 GADTs 的递归函数时,此语法非常有用,有关更详细的解释,请参见第 12.10 节。

方法定义提供了相同的功能。