diff options
| author | Enrico Tassi | 2016-05-13 17:44:45 +0200 |
|---|---|---|
| committer | Enrico Tassi | 2016-05-13 17:57:43 +0200 |
| commit | bd0befffb80c3086e3b451456cec24f3a12ac1f0 (patch) | |
| tree | 4cbf3f5189c2b74cab5841f2bc13b23801bbe8d8 /lib | |
| parent | b679eae9d3588f6cb91be174ab80a64fb5c434a4 (diff) | |
Dyn: simplify API introducing an Easy submodule
Now the casual Dyn user does not need to be a GADT guru
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/dyn.ml | 44 | ||||
| -rw-r--r-- | lib/dyn.mli | 13 | ||||
| -rw-r--r-- | lib/pp.ml | 8 |
3 files changed, 55 insertions, 10 deletions
diff --git a/lib/dyn.ml b/lib/dyn.ml index 676467e464..65d1442ac6 100644 --- a/lib/dyn.ml +++ b/lib/dyn.ml @@ -11,7 +11,7 @@ sig type 'a t end -module type S = +module type PreS = sig type 'a tag type t = Dyn : 'a tag * 'a -> t @@ -44,10 +44,23 @@ sig end val dump : unit -> (int * string) list + end -module Make(M : CSig.EmptyS) = -struct +module type S = +sig + include PreS + + module Easy : sig + val make_dyn : string -> ('a -> t) * (t -> 'a) + val inj : 'a -> 'a tag -> t + val prj : t -> 'a tag -> 'a option + end + +end + +module Make(M : CSig.EmptyS) = struct +module Self : PreS = struct (* Dynamics, programmed with DANGER !!! *) 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 end end +include Self + +module Easy = struct +(* now tags are opaque, we can do the trick *) +let make_dyn (s : string) = + (fun (type a) (tag : a tag) -> + let infun : (a -> t) = fun x -> Dyn (tag, x) in + let outfun : (t -> a) = fun (Dyn (t, x)) -> + match eq tag t with + | None -> assert false + | Some CSig.Refl -> x + in + (infun, outfun)) + (create s) + +let inj x tag = Dyn(tag,x) +let prj : type a. t -> a tag -> a option = + fun (Dyn(tag',x)) tag -> + match eq tag tag' with + | None -> None + | Some CSig.Refl -> Some x +end + +end + diff --git a/lib/dyn.mli b/lib/dyn.mli index c94fa764ba..448b11a18f 100644 --- a/lib/dyn.mli +++ b/lib/dyn.mli @@ -6,7 +6,8 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -(** Dynamics. Use with extreme care. Not for kids. *) +(** Dynamically typed values *) + module type TParam = sig type 'a t @@ -46,6 +47,16 @@ end val dump : unit -> (int * string) list +module Easy : sig + + (* To create a dynamic type on the fly *) + val make_dyn : string -> ('a -> t) * (t -> 'a) + + (* For types declared with the [create] function above *) + val inj : 'a -> 'a tag -> t + val prj : t -> 'a tag -> 'a option +end + end (** FIXME: use OCaml 4.02 generative functors when available *) @@ -57,12 +57,8 @@ module Dyn = Dyn.Make(struct end) type t = Dyn.t type 'a key = 'a Dyn.tag let create = Dyn.create -let inj x k = Dyn.Dyn (k, x) -let prj : type a. t -> a key -> a option = fun dyn k -> - let Dyn.Dyn (k', x) = dyn in - match Dyn.eq k k' with - | None -> None - | Some CSig.Refl -> Some x +let inj = Dyn.Easy.inj +let prj = Dyn.Easy.prj end |
