Functors and sharing:
module BSTree (Item : ordered) : BST
with type elt = Item.t =
struct
(* all that stuff a third time *)
end
include
Suppose 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)))
end
module 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 ^ "!"
end
What 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 int
s:
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)
end
cs2041.org