Id provides identifiers for types, and the ability to test (via
Id.same) at runtime if two identifiers are equal, and if so to get a proof of equality of their types. Unlike values of type
Type_equal.t, values of type
Id.t do have semantic content and must have a nontrivial runtime representation.
module Uid : sig ... end
Id.t contains a unique id that is distinct from the
Uid.t in any other
create ~name defines a new type identity. Two calls to
create will result in two distinct identifiers, even for the same arguments with the same type. If the type
'a doesn't support sexp conversion, then a good practice is to have the converter be
<:sexp_of< _ >>, (or
sexp_of_opaque, if not using pa_sexp).
val hash : _ t -> int
val name : _ t -> string
val hash_fold_t : Hash.state -> _ t -> Hash.state
same_witness t1 t2 and
same_witness_exn t1 t2 return a type equality proof iff the two identifiers are the same (i.e., physically equal, resulting from the same call to
create). This is a useful way to achieve a sort of dynamic typing.
same_witness does not allocate a
Some every time it is called.
same t1 t2 = is_some (same_witness t1 t2).