Gmap exposes the functor
Make which takes a key type (a
GADT 'a key)
and outputs a type-safe Map where each 'a key is associated with a 'a value.
This removes the need for additional packing. It uses OCaml's stdlib
type _ k = | A : int k | B : string k module K = struct type 'a t = 'a k let compare : type a b. a t -> b t -> (a, b) Gmap.Order.t = fun t t' -> let open Gmap.Order in match t, t' with | A, A -> Eq | A, _ -> Lt | _, A -> Gt | B, B -> Eq let pp : type a. Format.formatter -> a t -> a -> unit = fun ppf t v -> match t, v with | A, x -> Fmt.pf ppf "A %d" x | B, s -> Fmt.pf ppf "B %s" s end module M = Gmap.Make(K) let () = let m = M.empty in ... match M.find A m with | Some x -> Printf.printf "got %d\n" x | None -> Printf.printf "found nothing\n"
This is already an exhaustive pattern match: there is no need for another case
(for the constructor
B) since the type system knows that looking for
result in an
Motivation came from parsing of protocols which usually specify optional values
and extensions via a tag-length-value (TLV) mechanism: for a given tag the
structure of value is different - see for example IP options, TCP options, DNS
resource records, TLS hello extensions, etc.
Discussing this problem with Justus Matthiesen during summer 2017, we came up
with this design. Its main difference to Daniel C. Bünzli's
hmap is that in gmap the key-value GADT
type must be provided when instantiating the functor. In hmap, keys are created
API documentation is available online.
You need opam installed on your system. The command
opam install gmap
will install this library.