Module Base.Invariant
type nonrec 'a t= 'a Base__.Invariant_intf.t
module 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 frunsf (), and iffraises, wraps the exception in anError.tthat states "invariant failed" and includes both the exception raised byf, as well assexp_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 bycheck_awill show the parts that are opaque at top-level.
val check_field : 'a -> 'b t -> ('a, 'b) Field.t -> unitcheck_fieldis used when checking invariants usingFields.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 fields] 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)) ;;