模块(Module)是什么?我们首先看一下在OCaml内建的一些模块,比如可以先看一下List模块。首先让解释器将List模块的签名打印出来。这里有一个小技巧,我们可以将其复制一份自己的:
module MyList = List;;
然后就会打印出:
module MyList :
sig
val length : 'a list -> int
val hd : 'a list -> 'a
val tl : 'a list -> 'a list
val nth : 'a list -> int -> 'a
val rev : 'a list -> 'a list
val append : 'a list -> 'a list -> 'a list
val rev_append : 'a list -> 'a list -> 'a list
val concat : 'a list list -> 'a list
val flatten : 'a list list -> 'a list
val iter : ('a -> unit) -> 'a list -> unit
val map : ('a -> 'b) -> 'a list -> 'b list
val rev_map : ('a -> 'b) -> 'a list -> 'b list
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
val fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b
val iter2 : ('a -> 'b -> unit) -> 'a list -> 'b list -> unit
val map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
val rev_map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
val fold_left2 : ('a -> 'b -> 'c -> 'a) -> 'a -> 'b list -> 'c list -> 'a
val fold_right2 :
('a -> 'b -> 'c -> 'c) -> 'a list -> 'b list -> 'c -> 'c
val for_all : ('a -> bool) -> 'a list -> bool
val exists : ('a -> bool) -> 'a list -> bool
val for_all2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool
val exists2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool
val mem : 'a -> 'a list -> bool
val memq : 'a -> 'a list -> bool
val find : ('a -> bool) -> 'a list -> 'a
val filter : ('a -> bool) -> 'a list -> 'a list
val find_all : ('a -> bool) -> 'a list -> 'a list
val partition : ('a -> bool) -> 'a list -> 'a list * 'a list
val assoc : 'a -> ('a * 'b) list -> 'b
val assq : 'a -> ('a * 'b) list -> 'b
val mem_assoc : 'a -> ('a * 'b) list -> bool
val mem_assq : 'a -> ('a * 'b) list -> bool
val remove_assoc : 'a -> ('a * 'b) list -> ('a * 'b) list
val remove_assq : 'a -> ('a * 'b) list -> ('a * 'b) list
val split : ('a * 'b) list -> 'a list * 'b list
val combine : 'a list -> 'b list -> ('a * 'b) list
val sort : ('a -> 'a -> int) -> 'a list -> 'a list
val stable_sort : ('a -> 'a -> int) -> 'a list -> 'a list
val fast_sort : ('a -> 'a -> int) -> 'a list -> 'a list
val merge : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
end
这个小技巧告诉了我们List模块所有可以用的东西。
让我们假设虽然我们要利用List模块,但是出于某种原因,我们要排除某些功能并加入一些其它功能。我们可以制作一个自己的List模块的版本。下面的例子去掉了“val length…”函数。首先要注意“include List”。这个语句将会把List模块的定义给我们拉进来。重新将length函数定义为抛出一个异常,只要加两行代码就行了。
module MyList =
struct
include List
exception NO_LENGTH_ALLOWED
let length l = raise NO_LENGTH_ALLOWED
end;;
在下面一个例子中,我们就加入一个返回列表中任意一个元素的函数。我们还需要用到length函数,同时可能对于列表中没有任何元素的情况,还要加入另一个异常。
module MyList =
struct
include List
exception EMPTY_LIST
let rec rand_element l =
if l = [] then raise EMPTY_LIST
else
let len = float_of_int(List.length l) in
let r = Random.float 1.0 in
let e = int_of_float(len *. r) in
List.nth l e;;
end;;

