Module Relude_HMap

module Witness: { ... };

Witness contains a type t with an existential type variable - a type that we capture, but lose knowledge of once captured.

module type WITNESS = { ... };

WITNESS captures a type t with a Witness module for that type. Because Witness.t(_) is an extensible variant, we use += to add a constructor to that type.

type witness('a) = (module WITNESS with type t = 'a);

witness('a) is a type which captures a WITNESS module for the given type 'a.

let makeWitness: unit => (module WITNESS with type t = 'a);

makeWitness makes a Witness module for the given type a

type typeEq('a, 'b) =
| TypeEq : typeEq('a'a)
;

typeEq('a, 'b) contains a single constructor TypeEq which can only be constructed if 'a and 'b are the same types.

This is used for a type-level type equality check.

let typeEq: l r. witness('l) => witness('r) => option(typeEq('l'r));

typeEq checks whether the give witness types are equal.

module type KEY_META = { ... };

KEY_META is a module type signature which captures the type of a map key.

module type HMAP_TYPE = { ... };

HMAP_TYPE is a module type signature which captures the types and functions exposed by the HMap.

module WithKeyMeta: (KeyMeta: KEY_META) => HMAP_TYPE with type Key.keyMeta('a) = KeyMeta.t('a);

Make creates a Map module for the given KEY_META.

module WithKeyMetaUnit: { ... };

We include a default HMap implementation which uses unit as it's key meta type. Note that this default map type will not work in a type-safe way for functions that iterate over the map with keyValue functions, like fold, all, any, etc.

include WithKeyMetaUnit;
type keyImpl('a);

An abstract type for map keys

module Key = WithKeyMetaUnit.Key;

Key-related types and operations for an HMap

type t;

The abstract type of the HMap

let empty: t;

An empty HMap

let isEmpty: t => bool;

Indicates if the HMap is empty

let hasKey: keyImpl('a) => t => bool;

Indicates if the HMap has a value for the given key

let add: keyImpl('a) => 'a => t => t;

Adds the given key/value pair to the HMap

let singleton: keyImpl('a) => 'a => t;

Creates an HMap with the given key/value pair

let remove: keyImpl('a) => t => t;

Creates a new HMap that does not contain a value for the given key

let find: keyImpl('a) => t => option('a);

Looks up a value in the HMap for the given key

type keyValue =
| KeyValue(keyImpl('a), 'a) : keyValue
;

The type of a key/value pair in the HMap. The key captures the type of the corresponding value.

let forEach: (keyValue => unit) => t => unit;

Runs a side effect for each key/value pair in the HMap. Note: the KEY_META must provide appropriate functions for converting the existentially typed values into values of a known type.

let fold: (keyValue => 'a => 'a) => 'a => t => 'a;

Folds the HMap into a value. Note the KEY_META must provide appropriate functions for manipulating the values stored for each key.

let all: (keyValue => bool) => t => bool;

Indicates if all key/value pairs in the HMap satisfy the given predicate.

Note the KEY_META must provide appropriate functions for manipulating the values stored for each key.

let any: (keyValue => bool) => t => bool;

Indicates if any key/value pairs in the HMap satisfy the given predicate.

Note the KEY_META must provide appropriate functions for manipulating the values stored for each key.

let filter: (keyValue => bool) => t => t;

Creates a new HMap that only contains the key/value pairs that satisfy the given predicate.

Note the KEY_META must provide appropriate functions for manipulating the values stored for each key.

let size: t => int;

Gets the number of key/value pairs stored in this HMap.