Types 解决模块类型间接寻址产生的类型错误
以下代码生成类型错误Types 解决模块类型间接寻址产生的类型错误,types,module,ocaml,Types,Module,Ocaml,以下代码生成类型错误此表达式具有类型浮点,但预期表达式的类型为ModuleA.t,即使ModuleA.t和float相同,如ModuleA中所定义: module type ModuleT = sig type t val to_string : t -> string end module ModuleA : ModuleT = struct type t = float let to_string x = string_of_float x
此表达式具有类型浮点,但预期表达式的类型为ModuleA.t
,即使ModuleA.t
和float
相同,如ModuleA
中所定义:
module type ModuleT =
sig
type t
val to_string : t -> string
end
module ModuleA : ModuleT =
struct
type t = float
let to_string x = string_of_float x
end
let () =
let x = 3.0 in
Printf.printf "%s\n" (ModuleA.to_string x)
如果我不定义模块类型
ModuleT
,而只定义ModuleA
,则类型错误消失。如何在保留模块类型定义的同时解决类型错误?问题在于,您将t
的定义隐藏在ModuleT
中,鉴于您的问题中缺乏约束,显而易见的解决方案是完全定义它:
module type ModuleT =
sig
type t = float
val to_string : t -> string
end
但根据最初定义模块的原因,此解决方案可能不合适。例如,使用您定义的ModuleT
,您可以提供具有以下定义的ModuleB
:
module ModuleB : ModuleT =
struct
type t = int
let to_string x = string_of_int x
let make : int -> t = fun n -> n
end
let () =
let x = 3 in
Printf.printf "%s\n" (ModuleB.to_string (ModuleB.make x))
如果ModuleT
中的t
被约束为float
你就不能这样做,因为int
显然不会与float
统一起来,我定义模块类型的主要动机是能够限制我可以作为输入传递给模块函子的模块。但现在我才意识到,如果我定义了一个取模集
的模函子,而我没有定义模a
的类型,我仍然可以将它传递给函子,只要它实现了模集
中的内容。所以我想我最好的选择是只定义ModuleA
而不使用类型?这是一种常见的做法吗?为了澄清,我定义模块类型的动机也是能够在您的示例中定义类似于ModuleB
的东西,但请记住,我想定义一个函子,它可以取ModuleA
或ModuleB
,因为两者都有t
和To\u字符串
。考虑到这一点,是否建议定义ModuleA
和ModuleB
而不使用类型,并且只在模块函子输入中指定类型?只要您定义了类型,并且如果“ModuleA”和“ModuleB”在任何情况下都是子模块,您还可以添加约束作为文档。但我不认为它有任何其他用途。如果它们不合适,当你尝试使用它们的时候,它们都会失败。在另一种编程语言中有一种与你的目标相同的语言吗?(是不是接口ModuleT{…}类ModuleA实现了ModuleT{…}
?)是的,我基本上想要一个像你描述的接口