当你写一个程序使用两个文件amodule.mlbmodule.ml,它们中的每一个都自动定义一个模块,名字叫AmoduleBmodule,模块的内容就是你写到文件中的东西。

编译方法:

1
2
3
ocamlopt -c amodule.ml
ocamlopt -c bmodule.ml
ocamlopt -o hello amodule.cmx bmodule.cmx

为了避免使用;;

常这样写

1
2
3
4
5
6
open Amodule;;
hello ();;

open Amodule
let () =
hello ()

接口(Interfaces)和签名(Signatures)

如amodule.ml:

1
2
let message = "Hello"
let hello () = print_endline message

为隐藏message,可以编写amodule.mli文件

1
2
val hello : unit -> unit
(** 显示一句问候消息。 *)

==ocamldoc是什么?==

抽象类型Abstract Types 在mli文件中只给出类型名字 例如type date

子模块Submodules

1
2
3
module xxx = struct
...
end

子模块接口 模块类型 Module Types

1
2
3
4
5
6
7
8
9
10
11
12
13
module xxx : sig
...
end =
struct
...
end

module type xxx_type = sig
...
end
module xxx : xxx_type = struct
...
end

函子 仿函数Functors 和类C语言的Functors不太一样

用另一个模块来参数化的模块 允许传入一个类型作为参数 大概是类似于C++的模板

整型的集合

1
2
3
4
module Int_set = Set.Make (struct
type t = int
let compare = compare
end)

(可以看出 module只是起别名的作用 类似于let 重要的是struct-end对)

1
module String_set = Set.Make (String);;

带有一个参数的函子可以这样来定义:

1
2
3
module F (X : X_type) = struct
...
end

X_type是签名 此处是必须的

如果想要约束返回模块的签名

1
2
3
4
module F (X : X_type) : Y_type =
struct
...
end

创建一个包含之前模块的模块用

include xxx