include module type of struct include Bin_shape_lib.Std.Shape end
Shape.t
are constructed by the bin_shape
syntax extension from Ocaml type definitions & expressions.
There is a direct mapping from ocaml type definition syntax to the corresponding Shape.group
and from ocaml type expression syntax to the corresponding Shape.t
.
Tid.t
& Vid.t
are identifiers for type-constructors & type-vars. i.e. Given type 'a t = ...
Location.t
is required when constructing shapes for which evaluation might fail.
Uuid.t
is used by basetype
and annotate
.
group of mutually recursive type definitions
This function is generative; repeated calls create distinct groups
val record : (string * t) list -> t
val variant : (string * t list) list -> t
recursive apps within the current group
apps from outside the group
Built-in types and types with custom serialization: i.e. int,list,... To avoid accidental protocol compatibility, pass a UUID as the string
argument
a = annotate s t
creates a shape a
distinguished, but dependent on shape t
. Very much as record [(s,t)]
does. But with annotate
the ocaml record type does not exist.
Shape.Canonical.t
is the result of eval
uating a shape to a canonical form, and represents the shape of Ocaml types w.r.t. bin_io serialization.
The idea is that de-serialization is safe if the canonical-shape for the type produced by de-serialization is equivalent to the canonical-shape of the serialized type.
The representation is canonical, so equivalence is structural equality.
Canonical.t
also provides a useful human level description of a type.
A Canonical.t
can be `digested' to a Digest.t
, and except for nearly impossible hash collisions, equality of the digests implies equality of canonical-shapes and hence equivalence at the Shape.t level.
Canonical.t
may also be constructed with various functions: annotate, basetype, tuple, record, variant, poly_variant, fix, recurse, ..
which might be used when setting up unit tests or expected shapes.
eval t
returns the canonical-shape for a shape-expression Shape.t
. Type aliases are expanded, so that no Tid.t
or Vid.t
have significance in the resulting canonical-shape. Type-recursion, including non-regular recursion, is translated to the de-bruijn representation used in canonical-shapes.
eval_to_digest t
returns a hash-value direct from the Shape.t
, potentially avoiding the intermediate Canonical.t
from being constructed. This is important as the size of a canonical-shape might be exponential in terms of the size of the shape expression. The following holds: Digest.(eval_to_digest exp = Canonical.to_digest (eval exp))
val eval_to_digest_string : t -> string
eval_to_digest_string t
== Digest.to_hex (eval_to_digest t)
Convenience function useful for writing unit tests.