type_eq
provides a simple mechanism for constructing a type proof -- i.e.
a binding which knows that two types are the same, even if they are opaque.
Here's a short example:
module A : sig
(* These types are opaque outside of the [A] module. *)
type a
type b
(* This type is not the same as [a] or [b]. *)
type c
val a_b_proof : (a, b) Type_eq.t
(** [a_b_proof] proves that [a] and [b] are the same type -- otherwise a type
error will be thrown during its construction! *)
val a_c_proof : (a, c) Type_eq.t
(** [a_c_proof] proves that [a] and [c] are the same type.
Unfortunately, [a] and [c] are _not_ the same type, so this cannot be constructed! *)
end = struct
(* These types are indeed the same! *)
type a = string
type b = string
type c = int
let a_b_proof = Type_eq.Eq
let a_c_proof = Type_eq.Eq
(* This fails with a type error:
Error: Signature mismatch:
...
Values do not match:
val a_c_proof : ('a, 'a) Type_eq.t
is not included in
val a_c_proof : (b, c) Type_eq.t
The type (b, b) Type_eq.t is not compatible with the type
(b, c) Type_eq.t
Type b is not compatible with type c
*)
end
Sometimes you'll be working with types which are opaque -- as in the example above. This utility can be used to determine if two opaque types are indeed equal, which can allow you to cast between them, among other operations.
See the .mli
file for a fully-documented interface.
Note that a stripped-down version of this utility is included as Type.eq
in
OCaml 5+: https://github.com/ocaml/ocaml/blob/c2d00ef67b4af1e6ba90e77e4106770bbdd88a01/stdlib/type.ml#L18