在Ocaml中键入的一个奇怪示例
非常奇怪的是,这个ocaml代码段是由顶级输入的。看看结构,如果g的类型为int->int,如顶层所示,那么结构的在Ocaml中键入的一个奇怪示例,ocaml,typing,Ocaml,Typing,非常奇怪的是,这个ocaml代码段是由顶级输入的。看看结构,如果g的类型为int->int,如顶层所示,那么结构的hx=gx部分将无法获得统一的类型。那么,有人能澄清一下吗 module Mymodule : sig val h:int ->int val g: string-> string end = struct let g x = x let h x = g x end 这是topelevel的回应: module Mymodule : sig val
hx=gx
部分将无法获得统一的类型。那么,有人能澄清一下吗
module Mymodule : sig
val h:int ->int
val g: string-> string
end = struct
let g x = x
let h x = g x
end
这是topelevel的回应:
module Mymodule : sig val h : int -> int val g : string -> string end
我想说的是,
string->string
类型在导出之前不会应用于g
来自模块。在模块内部(因为您没有给它类型),它具有
'a->'a
。(免责声明:我不是一名模块专家,但我正在努力学习。)这里需要了解的重要一点是,OCaml以组合方式执行类型推断,即,它将首先推断结构的类型。。。结束
,然后它将根据信号匹配推断的类型。。。结束以验证结构是否确实实现了签名
例如,如果你写
module Monkey : sig val f : int -> int end =
struct
let f x = x
end
然后OCaml会很高兴,因为它将看到f
有一个多态类型'a->'a
,可以专门化为所需的类型int->int
。因为sig。。。end
使Monkey
不透明,即签名隐藏了实现,它将告诉您f
具有类型int->int
,即使实际实现具有多态类型
在您的特定情况下,OCaml首先推断g
的类型为'a->'a
,然后h
的类型也是'a->'a
。因此得出结论,该结构具有
sig val g : 'a -> 'a val h : 'a -> 'a end
接下来,将签名与给定签名进行匹配。因为类型为'a->'a
的函数可以专用于int->int
以及string->string
的函数,OCaml得出的结论是一切正常。当然,使用sig的整个要点。。。end
是为了使结构不透明(实现是隐藏的),这就是toplevel不公开多态类型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