为什么 OCaml 中的模块类型注释会导致此代码无法编译?
Why does a module type annotation in OCaml cause this code to not compile?
我正在使用 OCaml 中的地图模块。考虑以下代码来创建一个以整数作为键的映射:
module Int = struct
type t = int
let compare a b = a - b
end
module IntMap = Map.Make(Int)
let m = IntMap.(empty |> add 3 "hello")
一切正常。它的编译和行为符合我的预期。
但是,如果我为 Int
模块添加类型注释,那么顶行将变为:
module Int : Map.OrderedType = struct
最后一行导致编译出错:
let m = IntMap.(empty |> add 3 "hello")
^
Error: This expression has type int but an expression was expected of type
IntMap.key = Int.t
然而 IntMap.key
和 Int.t
都只是 int
的别名。此外,Int
模块的类型为 Map.OrderedType
。我知道这一点,因为这是 Map.Make
.
所需的类型
那么这里到底发生了什么?为什么提供不必要的类型注释会导致这样的错误。类型注释是否会导致更严格的可访问性并且与推断类型的行为不同?
这种注解严格限制了模块的接口。所以在我看来,通过添加注释,关于地图键类型的唯一已知信息由 Map.OrderedType
:
给出
module type OrderedType =
sig type t val compare : t -> t -> int end
除了t
类型存在并且它出现在compare
的参数中之外,它什么也没说。换句话说,您隐藏了类型 t
(也称为 IntMap.key
)与 int
.
类型相同的事实
您可以使用 with
重新介绍这个事实:
module Int : Map.OrderedType with type t = int = struct
type t = int
let compare a b = a - b
end
我正在使用 OCaml 中的地图模块。考虑以下代码来创建一个以整数作为键的映射:
module Int = struct
type t = int
let compare a b = a - b
end
module IntMap = Map.Make(Int)
let m = IntMap.(empty |> add 3 "hello")
一切正常。它的编译和行为符合我的预期。
但是,如果我为 Int
模块添加类型注释,那么顶行将变为:
module Int : Map.OrderedType = struct
最后一行导致编译出错:
let m = IntMap.(empty |> add 3 "hello")
^
Error: This expression has type int but an expression was expected of type
IntMap.key = Int.t
然而 IntMap.key
和 Int.t
都只是 int
的别名。此外,Int
模块的类型为 Map.OrderedType
。我知道这一点,因为这是 Map.Make
.
那么这里到底发生了什么?为什么提供不必要的类型注释会导致这样的错误。类型注释是否会导致更严格的可访问性并且与推断类型的行为不同?
这种注解严格限制了模块的接口。所以在我看来,通过添加注释,关于地图键类型的唯一已知信息由 Map.OrderedType
:
module type OrderedType =
sig type t val compare : t -> t -> int end
除了t
类型存在并且它出现在compare
的参数中之外,它什么也没说。换句话说,您隐藏了类型 t
(也称为 IntMap.key
)与 int
.
您可以使用 with
重新介绍这个事实:
module Int : Map.OrderedType with type t = int = struct
type t = int
let compare a b = a - b
end