Module Base__.Invariant
type nonrec 'a t
= 'a Base__.Invariant_intf.t
module type S = Base__.Invariant_intf.S
module type S1 = Base__.Invariant_intf.S1
module type S2 = Base__.Invariant_intf.S2
module type S3 = Base__.Invariant_intf.S3
val invariant : Base__.Source_code_position0.t -> 'a -> ('a -> Base.Sexp.t) -> (unit -> unit) -> unit
invariant here t sexp_of_t f
runsf ()
, and iff
raises, wraps the exception in anError.t
that 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_a
will show the parts that are opaque at top-level.
val check_field : 'a -> 'b t -> ('a, 'b) Base.Field.t -> unit
check_field
is 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)) ;;