Types 为什么在Ocaml中使用模块类型?
我混淆了Ocaml中的模块类型 我想知道在哪种情况下我们应该使用模块类型? 我通常使用.mli中的模块sig来公开一些细节,并将 .ml中对应的实现模块结构 例如: mli先生 .ml 因此,我认为Ocaml的模块类似于c中的.h和.c文件 我知道模块类型可以声明接口,但是接口与Java的接口不同 就像书中的一个例子:Types 为什么在Ocaml中使用模块类型?,types,functional-programming,ocaml,Types,Functional Programming,Ocaml,我混淆了Ocaml中的模块类型 我想知道在哪种情况下我们应该使用模块类型? 我通常使用.mli中的模块sig来公开一些细节,并将 .ml中对应的实现模块结构 例如: mli先生 .ml 因此,我认为Ocaml的模块类似于c中的.h和.c文件 我知道模块类型可以声明接口,但是接口与Java的接口不同 就像书中的一个例子: open Core.Std module type ID = sig type t val of_string : string -> t val to_
open Core.Std
module type ID = sig
type t
val of_string : string -> t
val to_string : t -> string
end
module String_id = struct
type t = string
let of_string x = x
let to_string x = x
end
module Username : ID = String_id
module Hostname : ID = String_id
type session_info = { user: Username.t;
host: Hostname.t;
when_started: Time.t;
}
let sessions_have_same_user s1 s2 =
s1.user = s2.host
前面的代码有一个bug:它将一个会话中的用户名与另一个会话中的主机进行比较,而在这两种情况下都应该比较用户名
模块类型似乎不能为其实现提供新的通用超类型
模块类型的实际应用与什么密切相关。阅读第章
函子的参数具有某种模块类型,其结果也是如此
函子被大量使用,大多数标准容器(如-s或-s)都是函子
如果开发泛型容器,您肯定需要函子和模块类型
(因此,函子和模块类型在Ocaml中的用处与模板在C++中的用处一样大)这里,模块类型用于向模块用户隐藏类型
t
当使用Username.t
或Hostname.t
时,不能依赖于字符串、整数或任何特定类型。模块类型使它们不透明,好像它们不是模块接口的一部分,而只是模块编写器将来将要更改的实现细节
基本上,模块用户只能通过模块功能对类型t
进行操作
编译器检查用户代码是否没有对这些类型
t
实际是什么进行任何假设,以便将来模块编写器可以在不破坏用户代码的情况下更改它们。如前所述,这里使用模块类型来实现类型t
的更抽象的视觉。当您将用户名
和主机名
定义为两个独立的模块时,这意味着它们在逻辑上必须不同,并且这些模块的签名是使用它们的唯一可能方式
但你说的是错的:
似乎模块类型不能为应用程序提供新的通用超级类型
这是执行
实际上,您可以确定Username.t
和Hostname.t
是相同的类型
module Username = (String_id : ID with type t = String_id.t)
module Hostname = (String_id : ID with type t = String_id.t)
Username.to_string (Hostname.of_string "hi")
在这里它是无用的,但有时它真的很有用。我假设,如果我的目的是隐藏一些细节,模块sig就足够了。Username.t和Hostname.t的通用超级类型是什么?我假设Ocaml不能与模块类型匹配。@qc1iu没有常见的超类型。毕竟,其中一个可能是
string
,另一个可能是int
。作为模块的用户,您无法看到确切的类型,只能利用模块提供的函数来处理该(抽象)类型。
open Core.Std
module type ID = sig
type t
val of_string : string -> t
val to_string : t -> string
end
module String_id = struct
type t = string
let of_string x = x
let to_string x = x
end
module Username : ID = String_id
module Hostname : ID = String_id
type session_info = { user: Username.t;
host: Hostname.t;
when_started: Time.t;
}
let sessions_have_same_user s1 s2 =
s1.user = s2.host
module Username = (String_id : ID with type t = String_id.t)
module Hostname = (String_id : ID with type t = String_id.t)
Username.to_string (Hostname.of_string "hi")