qc1*_*1iu 3 ocaml types functional-programming
我对Ocaml中的模块类型感到困惑.
我想知道在哪种情况下我们应该使用模块类型?
我通常在.mli中使用模块sig来公开一些细节,并在.ml中放置相应的实现模块结构.
例如:
.mli
module A:
sig
type t = T of string
end
Run Code Online (Sandbox Code Playgroud)
.ml
module A =
struct
type t = T of string
end
Run Code Online (Sandbox Code Playgroud)
出于这个原因,我认为Ocaml的模块就像C.中的.h和.c文件一样.
我知道,模块类型可以声明一个接口,但接口是不是因为Java的接口相同.
就像书中的一个例子:
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
Run Code Online (Sandbox Code Playgroud)
上面的代码有一个错误:它将一个会话中的用户名与另一个会话中的主机进行比较,当它应该在两种情况下比较用户名时.
似乎模块类型无法为其实现提供新的通用超类型.
什么是模块类型的真正应用?
这里,模块类型用于向模块的用户隐藏类型t.
当一个人使用Username.t或者Hostname.t不能依赖那些类型的字符串,整数或任何特定类型.模块类型使它们不透明,就好像它们不是模块接口的一部分,而只是模块编写器将来要改变的实现细节.
基本上,模块的用户只能t通过模块功能对类型进行操作.
编译器检查用户代码是否对这些类型t实际是什么做出任何假设,以便将来模块编写者可以在不破坏用户代码的情况下更改它们.