1
(* Example of algorithm parametrized with modules *)
3
let sort (type s) set l =
4
let module Set = (val set : Set.S with type elt = s) in
5
Set.elements (List.fold_right Set.add l Set.empty)
7
let make_set (type s) cmp =
8
let module S = Set.Make(struct
12
(module S : Set.S with type elt = s)
16
(fun set -> sort set l)
17
[ make_set compare; make_set (fun x y -> compare y x) ]
20
print_endline (String.concat " " (List.map (String.concat "/") (both ["abc";"xyz";"def"])))
23
(* Hiding the internal representation *)
27
val to_string: t -> string
32
let create (type s) to_string apply x =
35
let to_string = to_string
39
(module M : S with type t = s)
41
let forget (type s) x =
42
let module M = (val x : S with type t = s) in
46
let module M = (val x : S) in
47
print_endline (M.to_string M.x)
50
let module M = (val x : S) in
58
let int = forget (create string_of_int succ 0) in
59
let str = forget (create (fun s -> s) (fun s -> s ^ s) "X") in
60
List.iter print (List.map apply [int; apply int; apply (apply str)])
63
(* Existential types + type equality witnesses -> pseudo GADT *)
67
val apply: ('a, 'b) t -> 'a -> 'b
69
val sym: ('a, 'b) t -> ('b, 'a) t
71
type ('a, 'b) t = unit
72
let apply _ = Obj.magic
79
module type PAIR = sig
83
val eq: (t, t1 * t2) TypEq.t
89
| Int of ('a, int) TypEq.t
90
| String of ('a, string) TypEq.t
91
| Pair of (module PAIR with type t = 'a)
93
module type PAIR = sig
97
val eq: (t, t1 * t2) TypEq.t
103
| Int of ('a, int) TypEq.t
104
| String of ('a, string) TypEq.t
105
| Pair of (module PAIR with type t = 'a)
110
let int = Int TypEq.refl
112
let str = String TypEq.refl
114
let pair (type s1) (type s2) t1 t2 =
115
let module P = struct
123
let pair = (module P : PAIR with type t = s1 * s2) in
126
module rec Print : sig
127
val to_string: 'a Typ.typ -> 'a -> string
129
let to_string (type s) t x =
131
| Int eq -> string_of_int (TypEq.apply eq x)
132
| String eq -> Printf.sprintf "%S" (TypEq.apply eq x)
134
let module P = (val p : PAIR with type t = s) in
135
let (x1, x2) = TypEq.apply P.eq x in
136
Printf.sprintf "(%s,%s)" (Print.to_string P.t1 x1) (Print.to_string P.t2 x2)
140
print_endline (Print.to_string int 10);
141
print_endline (Print.to_string (pair int (pair str int)) (123, ("A", 456)))