为什么在Ocaml中使用模块类型?

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)

上面的代码有一个错误:它将一个会话中的用户名与另一个会话中的主机进行比较,当它应该在两种情况下比较用户名时.

似乎模块类型无法为其实现提供新的通用超类型.

什么是模块类型的真正应用?

chi*_*chi 6

这里,模块类型用于向模块的用户隐藏类型t.

当一个人使用Username.t或者Hostname.t不能依赖那些类型的字符串,整数或任何特定类型.模块类型使它们不透明,就好像它们不是模块接口的一部分,而只是模块编写器将来要改变的实现细节.

基本上,模块的用户只能t通过模块功能对类型进行操作.

编译器检查用户代码是否对这些类型t实际是什么做出任何假设,以便将来模块编写者可以在不破坏用户代码的情况下更改它们.