这里要理解的重要一点是,OCaml 以组合方式执行类型推断,即,它会首先推断类型,struct ... end
然后才会匹配推断的类型,sig ... end
以验证结构确实实现了签名。
例如,如果你写
module Monkey : sig val f : int -> int end =
struct
let f x = x
end
然后 OCaml 会很高兴,因为它会看到它f
具有'a -> 'a
可以专门用于所需类型的多态类型int -> int
。因为sig ... end
使得Monkey
不透明,即签名隐藏了实现,它会告诉你f
有 type int -> int
,即使实际的实现有一个多态类型。
在您的特定情况下,OCaml 首先推断出g
具有 type 'a -> 'a
,然后推断出 of 的类型h
也是'a -> 'a
如此。因此得出结论,该结构具有类型
sig val g : 'a -> 'a val h : 'a -> 'a end
接下来,将签名与给定的签名进行匹配。因为类型的函数'a -> 'a
可以被专门化int -> int
,string -> string
OCaml 得出的结论是一切都很好。当然,使用的全部意义sig ... end
在于使结构不透明(实现是隐藏的),这就是为什么顶层不暴露and 的多态类型的g
原因h
。
这是另一个显示 OCaml 工作原理的示例:
module Cow =
struct
let f x = x
let g x = f [x]
let a = f "hi"
end
module Bull : sig
val f : int -> int
val g : 'b * 'c -> ('b * 'c) list
val a : string
end = Cow
回应是
module Cow :
sig
val f : 'a -> 'a
val g : 'a -> 'a list
val a : string
end
module Bull :
sig
val f : int -> int
val g : 'a * 'b -> ('a * 'b) list
val a : string end
end