Skip to content

Commit bd0beff

Browse files
committed
Dyn: simplify API introducing an Easy submodule
Now the casual Dyn user does not need to be a GADT guru
1 parent b679eae commit bd0beff

File tree

5 files changed

+57
-34
lines changed

5 files changed

+57
-34
lines changed

lib/dyn.ml

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ sig
1111
type 'a t
1212
end
1313

14-
module type S =
14+
module type PreS =
1515
sig
1616
type 'a tag
1717
type t = Dyn : 'a tag * 'a -> t
@@ -44,10 +44,23 @@ sig
4444
end
4545

4646
val dump : unit -> (int * string) list
47+
4748
end
4849

49-
module Make(M : CSig.EmptyS) =
50-
struct
50+
module type S =
51+
sig
52+
include PreS
53+
54+
module Easy : sig
55+
val make_dyn : string -> ('a -> t) * (t -> 'a)
56+
val inj : 'a -> 'a tag -> t
57+
val prj : t -> 'a tag -> 'a option
58+
end
59+
60+
end
61+
62+
module Make(M : CSig.EmptyS) = struct
63+
module Self : PreS = struct
5164
(* Dynamics, programmed with DANGER !!! *)
5265

5366
type 'a tag = int
@@ -108,3 +121,28 @@ let fold f m accu = Int.Map.fold (fun k v accu -> f (Any (k, v)) accu) m accu
108121
end
109122

110123
end
124+
include Self
125+
126+
module Easy = struct
127+
(* now tags are opaque, we can do the trick *)
128+
let make_dyn (s : string) =
129+
(fun (type a) (tag : a tag) ->
130+
let infun : (a -> t) = fun x -> Dyn (tag, x) in
131+
let outfun : (t -> a) = fun (Dyn (t, x)) ->
132+
match eq tag t with
133+
| None -> assert false
134+
| Some CSig.Refl -> x
135+
in
136+
(infun, outfun))
137+
(create s)
138+
139+
let inj x tag = Dyn(tag,x)
140+
let prj : type a. t -> a tag -> a option =
141+
fun (Dyn(tag',x)) tag ->
142+
match eq tag tag' with
143+
| None -> None
144+
| Some CSig.Refl -> Some x
145+
end
146+
147+
end
148+

lib/dyn.mli

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
(* * GNU Lesser General Public License Version 2.1 *)
77
(************************************************************************)
88

9-
(** Dynamics. Use with extreme care. Not for kids. *)
9+
(** Dynamically typed values *)
10+
1011
module type TParam =
1112
sig
1213
type 'a t
@@ -46,6 +47,16 @@ end
4647

4748
val dump : unit -> (int * string) list
4849

50+
module Easy : sig
51+
52+
(* To create a dynamic type on the fly *)
53+
val make_dyn : string -> ('a -> t) * (t -> 'a)
54+
55+
(* For types declared with the [create] function above *)
56+
val inj : 'a -> 'a tag -> t
57+
val prj : t -> 'a tag -> 'a option
58+
end
59+
4960
end
5061

5162
(** FIXME: use OCaml 4.02 generative functors when available *)

lib/pp.ml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,8 @@ module Dyn = Dyn.Make(struct end)
5757
type t = Dyn.t
5858
type 'a key = 'a Dyn.tag
5959
let create = Dyn.create
60-
let inj x k = Dyn.Dyn (k, x)
61-
let prj : type a. t -> a key -> a option = fun dyn k ->
62-
let Dyn.Dyn (k', x) = dyn in
63-
match Dyn.eq k k' with
64-
| None -> None
65-
| Some CSig.Refl -> Some x
60+
let inj = Dyn.Easy.inj
61+
let prj = Dyn.Easy.prj
6662

6763
end
6864

library/libobject.ml

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,9 @@ let object_tag (Dyn.Dyn (t, _)) = Dyn.repr t
7878
let cache_tab =
7979
(Hashtbl.create 17 : (string,dynamic_object_declaration) Hashtbl.t)
8080

81-
let make_dyn (type a) (tag : a Dyn.tag) =
82-
let infun x = Dyn.Dyn (tag, x) in
83-
let outfun : (Dyn.t -> a) = fun dyn ->
84-
let Dyn.Dyn (t, x) = dyn in
85-
match Dyn.eq t tag with
86-
| None -> assert false
87-
| Some Refl -> x
88-
in
89-
(infun, outfun)
90-
9181
let declare_object_full odecl =
9282
let na = odecl.object_name in
93-
let tag = Dyn.create na in
94-
let (infun, outfun) = make_dyn tag in
83+
let (infun, outfun) = Dyn.Easy.make_dyn na in
9584
let cacher (oname,lobj) = odecl.cache_function (oname,outfun lobj)
9685
and loader i (oname,lobj) = odecl.load_function i (oname,outfun lobj)
9786
and opener i (oname,lobj) = odecl.open_function i (oname,outfun lobj)

library/summary.ml

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,8 @@ let summaries = ref Int.Map.empty
2222

2323
let mangle id = id ^ "-SUMMARY"
2424

25-
let make_dyn (type a) (tag : a Dyn.tag) =
26-
let infun x = Dyn.Dyn (tag, x) in
27-
let outfun : (Dyn.t -> a) = fun dyn ->
28-
let Dyn.Dyn (t, x) = dyn in
29-
match Dyn.eq t tag with
30-
| None -> assert false
31-
| Some Refl -> x
32-
in
33-
(infun, outfun)
34-
3525
let internal_declare_summary hash sumname sdecl =
36-
let tag = Dyn.create (mangle sumname) in
37-
let (infun, outfun) = make_dyn tag in
26+
let (infun, outfun) = Dyn.Easy.make_dyn (mangle sumname) in
3827
let dyn_freeze b = infun (sdecl.freeze_function b)
3928
and dyn_unfreeze sum = sdecl.unfreeze_function (outfun sum)
4029
and dyn_init = sdecl.init_function in

0 commit comments

Comments
 (0)