OCaml library : Type.Id (original) (raw)

Module Type.Id

module Id: sig .. end

Type identifiers.

A type identifier is a value that denotes a type. Given two type identifiers, they can be tested for equality to prove they denote the same type. Note that:

See an example of use.


Type identifiers

type !'a t

The type for identifiers for type 'a.

val make : unit -> 'a [t](Type.Id.html#TYPEt)

make () is a new type identifier.

val uid : 'a [t](Type.Id.html#TYPEt) -> int

uid id is a runtime unique identifier for id.

val provably_equal : 'a [t](Type.Id.html#TYPEt) -> 'b [t](Type.Id.html#TYPEt) -> ('a, 'b) [Type.eq](Type.html#TYPEeq) option

provably_equal i0 i1 is Some Equal if identifier i0 is equal to i1 and None otherwise.

Example

The following shows how type identifiers can be used to implement a simple heterogeneous key-value dictionary. In contrast toMap values whose keys map to a single, homogeneous type of values, this dictionary can associate a different type of value to each key.

``

(** Heterogeneous dictionaries. *)

module Dict : sig type t

| | (** The type for dictionaries. *) | | ----------------------------------- |

`

type 'a key `

| | (** The type for keys binding values of type 'a. *) | | ----------------------------------------------------- |

`

val key : unit -> 'a key `

| | (** key () is a new dictionary key. *) | | ---------------------------------------- |

`

val empty : t `

| | (** empty is the empty dictionary. *) | | --------------------------------------- |

`

val add : 'a key -> 'a -> t -> t `

| | (** add k v d is d with k bound to v. *) | | ------------------------------------------ |

`

val remove : 'a key -> t -> t `

| | (** remove k d is d with the last binding of k removed. *) | | ------------------------------------------------------------ |

`

val find : 'a key -> t -> 'a option `

| | (** find k d is the binding of k in d, if any. *) | | --------------------------------------------------- |

` end = struct type 'a key = 'a Type.Id.t type binding = B : 'a key * 'a -> binding type t = (int * binding) list

let key () = Type.Id.make () let empty = [] let add k v d = (Type.Id.uid k, B (k, v)) :: d let remove k d = List.remove_assoc (Type.Id.uid k) d let find : type a. a key -> t -> a option = fun k d -> match List.assoc_opt (Type.Id.uid k) d with | None -> None | Some (B (k', v)) -> match Type.Id.provably_equal k k' with | Some Type.Equal -> Some v | None -> assert false end `