module Invariant_intf:sig..end
S, S1,
S2, S3) for each arity of type. Usage looks like:
type t
include Invariant.S with type t := t
or
type 'a t
include Invariant.S1 with type 'a t := 'a t
S, S1,
S2, S3) for each arity of type. Usage looks like:
type t
include Invariant.S with type t := t
or
type 'a t
include Invariant.S1 with type 'a t := 'a t
type'at ='a -> unit
type'ainv ='a t
module type S =sig..end
module type S1 =sig..end
module type S2 =sig..end
module type S3 =sig..end
module type Invariant =sig..end
S, S1,
S2, S3) for each arity of type. Usage looks like:
type t
include Invariant.S with type t := t
or
type 'a t
include Invariant.S1 with type 'a t := 'a t
invariant 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 ... )
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;
}
with fields
let invariant t : unit =
invariant "Foo.invariant" t <:sexp_of< t >> (fun () ->
let check f = Invariant.check_field t f in
Fields.iter
~foo:(check Foo.invariant)
~bar:(check Bar.invariant))
;;