include Base__.Invariant_intf.Invariantmodule type S = Base__.Invariant_intf.Smodule type S1 = Base__.Invariant_intf.S1module type S2 = Base__.Invariant_intf.S2module type S3 = Base__.Invariant_intf.S3val invariant : Base__.Source_code_position0.t ‑> 'a ‑> ('a ‑> Sexp.t) ‑> (unit ‑> unit) ‑> unitinvariant here t sexp_of_t f runs f (), and if f raises, wraps the exception
in an Error.t that states "invariant failed" and includes both the exception
raised by f, as well as sexp_of_t t. Idiomatic usage looks like:
invariant [%here] t <:sexp_of< t >> (fun () ->
... check t's invariants ... )
For polymorphic types:
let invariant check_a t =
Invariant.invariant [%here] t <:sexp_of< _ t >> (fun () -> ... )
It's okay to use <:sexp_of< _ t >> because the exceptions raised by check_a
will show the parts that are sexp_opaque at top-level.
check_field is used when checking invariants using Fields.iter. It wraps an
exception raised when checking a field with the field's name. Idiomatic usage looks
like:
type t =
{ foo : Foo.t;
bar : Bar.t;
}
[@@deriving_inline fields][@@@end]
let invariant t : unit =
Invariant.invariant [%here] t [%sexp_of: t] (fun () ->
let check f = Invariant.check_field t f in
Fields.iter
~foo:(check Foo.invariant)
~bar:(check Bar.invariant))
;;