Functors and sharing:
module BSTree (Item : ordered) : BST
with type elt = Item.t =
struct
(* all that stuff a third time *)
endincludeSuppose we want to make a “wrapper” module for BSTs…
module BSTWrapper(B : BST) = struct
type elt = B.elt
type t = B.t
let empty = B.empty (* and so on *)
(* new stuff here: *)
let size t = fold (fun a _ -> a+1) 0 t
(* ... *)Instead of all that typing we can use include:
module BSTWrapper(B : BST) = struct
include B
let size t = B.fold (fun a _ -> a+1) 0 t
let to_sorted_list t =
B.fold (fun a e -> e::a) [] t
let min t = B.fold (function None -> fun v -> (Some v) | v -> fun _ -> v) None t
let max t = if t = B.empty then None else Some (List.hd (List.rev (to_sorted_list t)))
endmodule M1 : sig val greet : string -> string end = struct
let pre s = String.uppercase_ascii s
let greet s = "HELLO " ^ (pre s)
end
module M2 = struct
include M1
let pre s = s^"!"
end
module M3 = struct
include M1
let print s = print_endline (greet s)
let greet s = s ^ "!"
endWhat is the result of:
M2.greet "world"?
M3.print "friend"?
M3.greet "friend"?
include also works in signatures, and can be modified with sharing:
Define a “wrapper” functor that turns an IntSetSig module into a NatSet module by raising an exception when adding or testing negative ints:
module NatSetWrapper(S : IntSetSig) : IntSetSig = struct
include S
let add x s = if x < 0 then invalid_arg "NatSet.add" else (S.add x s)
let mem x s = if x < 0 then invalid_arg "NatSet.mem" else (S.mem x s)
let of_list ls = if List.exists ((>) 0) ls
then invalid_arg "NatSet.of_list"
else (S.of_list ls)
endcs2041.org