Module OCaml中模块中的抽象类型

Module OCaml中模块中的抽象类型,module,ocaml,signature,Module,Ocaml,Signature,我在OCaml中有非常简单的签名和模块: module type S = sig type t val y : t end;; 及 我不能像这样使用构造 M2.y 除非我将模块指定为 module M2 : S with type t = int = struct ... 为什么会这样?已经有声明指出,类型t=intM2.y的混凝土int值确实不可用,因为满足以下两个条件: y的类型在签名S中是抽象的 没有类型t=。。。那里 模块M2相对于签名S是不透明的 换句话说,它通过符号S

我在OCaml中有非常简单的签名和模块:

module type S = sig
  type t 
  val y : t
end;;

我不能像这样使用构造

M2.y
除非我将模块指定为

module M2 : S with type t = int = struct ...
为什么会这样?已经有声明指出,类型t=int

M2.y的混凝土int值确实不可用,因为满足以下两个条件:

y的类型在签名S中是抽象的 没有类型t=。。。那里

模块M2相对于签名S是不透明的 换句话说,它通过符号S限制为签名S

因此,您确实获得:

let test = M2.y ;;
(* val test : M2.t = <abstr> *)
但在实践中,这不是很有趣,因为你失去了一般性。然而,一种更有趣的方法是在签名中添加一个计算器或一个漂亮的打印机函数,例如下面的int_/t值:

否则,如果模块M2是透明的,则可以获得:

 module type S = sig
   type t = int
   val y : t
 end

 module M2 : S = struct
   type t = int
   let x = 1
   let y = x+2
 end

 let test = M2.y ;;
 (* val test : M2.t = 3 *)
 module type S = sig
   type t
   val y : t
 end

 module M2 (* :S *) = struct
   type t = int
   let x = 1
   let y = x+2
 end

 let test = M2.y ;;
 (* val test : int = 3 *)
最后,值得注意的是,除了抽象类型的特性之外,OCaml还提供了私有类型的特性,可以将其视为模块化开发中使用的具体类型和抽象类型之间的折衷。有关此概念的更多详细信息,请参见示例。

M2.y的具体int值确实不可用,因为满足以下两个条件:

y的类型在签名S中是抽象的 没有类型t=。。。那里

模块M2相对于签名S是不透明的 换句话说,它通过符号S限制为签名S

因此,您确实获得:

let test = M2.y ;;
(* val test : M2.t = <abstr> *)
但在实践中,这不是很有趣,因为你失去了一般性。然而,一种更有趣的方法是在签名中添加一个计算器或一个漂亮的打印机函数,例如下面的int_/t值:

否则,如果模块M2是透明的,则可以获得:

 module type S = sig
   type t = int
   val y : t
 end

 module M2 : S = struct
   type t = int
   let x = 1
   let y = x+2
 end

 let test = M2.y ;;
 (* val test : M2.t = 3 *)
 module type S = sig
   type t
   val y : t
 end

 module M2 (* :S *) = struct
   type t = int
   let x = 1
   let y = x+2
 end

 let test = M2.y ;;
 (* val test : int = 3 *)

最后,值得注意的是,除了抽象类型的特性之外,OCaml还提供了私有类型的特性,可以将其视为模块化开发中使用的具体类型和抽象类型之间的折衷。有关此概念的更多详细信息,请参见示例。

如果不解释模块签名和抽象类型的整个概念,我不知道如何回答此问题,最好从一本合适的书中了解。我建议你读一下:如果不解释模块签名和抽象类型的整个概念,我不知道如何回答这个问题,你最好从一本合适的书上了解一下。我建议你读一下: