OCaml模块

原文地址:http://www.ocaml-tutorial.org/modules,翻译:ShiningRay

模块(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;;