package gmap

  1. Overview
  2. Docs
Heterogenous maps over a GADT

Install

Dune Dependency

Authors

Maintainers

Sources

gmap-0.2.0.tbz
sha256=00c6a2186c0c9908f6057566ac72de062b26ac5b1f5d0d78721c8526a580884d
md5=fbf9d1d5a38c2c86ef2f122e22359896

Description

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 Map data structure.

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 A will result in an int.

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 dynamically.

Published: 24 Jun 2018

README

Gmap - heterogenous maps over a GADT

0.2.0

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 Map data structure.

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 A will result in an int.

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 dynamically.

Documentation

API documentation is available online.

Installation

You need opam installed on your system. The command

opam install gmap

will install this library.

Dependencies (5)

  1. fmt
  2. topkg build
  3. ocamlbuild build
  4. ocamlfind build
  5. ocaml >= "4.04.2"

Dev Dependencies

None

Used by (1)

  1. icalendar < "0.1.1"

Conflicts

None

OCaml

Innovation. Community. Security.