#25 Parametric Abstraction with Functors and Modules
Modules package types and values behind an interface, while functors are modules parameterized by modules, so they act like compile-time functions that build new modules from given implementations.
(* abstract *)
module type ORDERED = sig
type t
val compare : t -> t -> int
end
(* abstract max *)
module MakeAnyMax (Ord : ORDERED) = struct
let anyMax lst =
match lst with
| [] -> None
| x :: xs ->
Some (List.fold_left (fun acc y -> if Ord.compare y acc > 0 then y else acc) x xs)
end
(* instance *)
module IntMax = MakeAnyMax(struct type t = int let compare = compare end)
module StringMax = MakeAnyMax(struct type t = string let compare = compare end)
(* example *)
let () =
(let open IntMax in
match anyMax [1;5;3] with
| Some m -> Printf.printf "%d\n" m
| None -> ());
(let open StringMax in
match anyMax ["a";"z";"m"] with
| Some s -> Printf.printf "%s\n" s
| None -> ())
Here a module type (signature) ORDERED, alongside functor MakeAnyMax which takes any module satisfying ORDERED and produces a module exposing anyMax : Ord.t list -> Ord.t option.
Depends on: Applies to: Applied by: