let build_sloq n =
let rec qbuild i q = if i=0 then q
else qbuild (i-1) (Queue.enqueue q i)
in qbuild n Queue.empty_q
let rec empty_sloq q = if Queue.is_empty q then ()
else let q' = Queue.dequeue q in
empty_sloq q'let build_fq n =
let rec qbuild i q = if i=0 then q
else qbuild (i-1) (FastQ.enqueue q i)
in qbuild FastQ.empty_q
let rec empty_fq q = if FastQ.is_empty q then ()
else let q' = FastQ.dequeue q in
empty_fq q'This looks like an opportunity for code reuse…
A functor is a module that acts on one or more other modules as arguments:
Module typing is “structural”:
module SlackerQ = struct
type 'a q = Nevs of 'a | Whatevs
let empty_q = Whatevs
let is_empty q = true
let enqueue q x = Whatevs
exception OMG
let peek q = raise OMG
let dequeue q = Whatevs
exception EmptyQ = OMG
endModule M matches signature S if it has the minimal functionality (matching names, types) required by S.
Signatures and Structures can be anonymous…
But they are not “first-class” types and values:
Functors offer another approach to polymorphism:
module type OrdSig = sig
type t
val compare : t -> t -> int
end
module BSTree (Item : OrdSig) =
struct
type elt = Item.t
type t = Empty | Node of elt*t*t
let empty = Empty
let rec search t x = (* some stuff *)
let rec insert t x = (* more stuff *)
let rec fold f acc t = (* you know *)
end
module StringBST = BSTree(String)Suppose we want to make the BSTree.t type abstract…
Problem: BST.elt is abstract. It can be “opened” with a sharing constraint:
module BSTree (Item : ordered) : BST
with type elt = Item.t =
struct
(* all that stuff a third time *)
endHow would we use the BSTree functor to make a case-insensitive BSTree?
OCaml’s Set.Make, Map.Make functors work similarly…
cs2041.org