Base.InvariantThis module defines signatures that are to be included in other signatures to ensure a consistent interface to invariant-style functions. There is a signature (S, S1, S2, S3) for each arity of type. Usage looks like:
type t
include Invariant.S with type t := tor
type 'a t
include Invariant.S1 with type 'a t := 'a tmodule type S = sig ... endmodule type S1 = sig ... endmodule type S2 = sig ... endmodule type S3 = sig ... endval invariant : 
  Lexing.position ->
  '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 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 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))
;;