123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179(** For making an abstract version of a type that ensures a validation check has passed.
Suppose one wants to have a type of positive integers:
{[
module Positive_int = Validated.Make (struct
type t = int
let here = [%here]
let validate = Int.validate_positive
end)
]}
With this, one is certain that any value of type [Positive_int.t] has passed
[Int.validate_positive].
One can call [Positive_int.create_exn n] to create a new positive int from an [n],
which will of course raise if [n <= 0]. One can call [Positive_int.raw positive_int]
to get the [int] from a [Positive_int.t]. *)open!ImportmoduletypeRaw=sigtypet[@@derivingsexp](** [here] will appear in validation-failure error messages. *)valhere:Source_code_position.tvalvalidate:tValidate.checkendmoduletypeRaw_bin_io=sigtypet[@@derivingbin_io]includeRawwithtypet:=t(** [validate_binio_deserialization] controls whether when the binio representation of a
value is deserialized, the resulting value is validated. Whether one needs to
validate values upon deserialization depends on how serialization is being used. If
one only ever serializes/deserializes so that the validation function is the same on
both ends, then one need not validate upon deserialization, because only values that
already pass the validation function can be serialized.
If the validation functions in the serializer and deserializer may be different,
e.g. because of two different versions of the code compiled at different times, then
it is possible to serialize a value that may fail validation upon deserialization.
In that case, having [validate_binio_deserialization = true] is necessary to prevent
creating values that don't pass the validation function. *)valvalidate_binio_deserialization:boolendmoduletypeRaw_bin_io_compare_hash_sexp=sigtypet[@@derivingcompare,hash]includeRaw_bin_iowithtypet:=tend(** [S_allowing_substitution] is the same as [S], but allows writing interfaces like:
{[
type t [@@deriving bin_io, compare, ...]
include Validated.S_allowing_substitution with type t := t and type raw := my_raw_type
]}
which is not possible with [S] due to the fact that it constrains [t]. The downside
is that you can no longer directly coerce [t] to be a [raw] but:
+ You can use the [raw] function instead
+ You can match on [type_equal] to do the coercion if you really need to (although
that's still a bit clunkier than a direct coercion would be)
*)moduletypeS_allowing_substitution=sigtype('raw,'witness)validatedtypewitnesstyperawtypet[@@derivingsexp]valcreate:raw->tOr_error.tvalcreate_exn:raw->tvalraw:t->rawvalcreate_stable_witness:rawStable_witness.t->tStable_witness.tvaltype_equal:(t,(raw,witness)validated)Type_equal.tendmoduletypeS=sigtype('raw,'witness)validatedtypewitnesstyperawtypet=(raw,witness)validatedincludeS_allowing_substitutionwithtypet:=tandtyperaw:=rawandtypewitness:=witnessandtype('raw,'witness)validated:=('raw,'witness)validatedendmoduletypeS_bin_io=sigincludeSincludesigtypet=(raw,witness)validated[@@derivingbin_io]endwithtypet:=tendmoduletypeS_bin_io_compare_hash_sexp=sigincludeSincludesigtypet=(raw,witness)validated[@@derivingbin_io,compare,hash]endwithtypet:=tendmoduletypeValidated=sigtype('raw,'witness)t=private'rawvalraw:('raw,_)t->'rawmoduletypeRaw=RawmoduletypeS=Swithtype('a,'b)validated:=('a,'b)tmoduletypeS_allowing_substitution=S_allowing_substitutionwithtype('a,'b)validated:=('a,'b)tmoduletypeS_bin_io=S_bin_iowithtype('a,'b)validated:=('a,'b)tmoduletypeS_bin_io_compare_hash_sexp=S_bin_io_compare_hash_sexpwithtype('a,'b)validated:=('a,'b)tmoduleMake(Raw:Raw):Swithtyperaw:=Raw.tmoduleMake_binable(Raw:Raw_bin_io):S_bin_iowithtyperaw:=Raw.t(** [Make_bin_io_compare_hash_sexp] is useful for stable types. *)moduleMake_bin_io_compare_hash_sexp(Raw:Raw_bin_io_compare_hash_sexp):S_bin_io_compare_hash_sexpwithtyperaw:=Raw.tmoduleAdd_bin_io(Raw:sigtypet[@@derivingbin_io]includeRaw_bin_iowithtypet:=tend)(Validated:Swithtyperaw:=Raw.t):sigtypet[@@derivingbin_io]endwithtypet:=Validated.tmoduleAdd_compare(Raw:sigtypet[@@derivingcompare]includeRawwithtypet:=tend)(Validated:Swithtyperaw:=Raw.t):sigtypet[@@derivingcompare]endwithtypet:=Validated.tmoduleAdd_hash(Raw:sigtypet[@@derivinghash]includeRawwithtypet:=tend)(Validated:Swithtyperaw:=Raw.t):sigtypet[@@derivinghash]endwithtypet:=Validated.tmoduleAdd_typerep(Raw:sigtypet[@@derivingtyperep]includeRawwithtypet:=tend)(Validated:Swithtyperaw:=Raw.t):sigtypet[@@derivingtyperep]endwithtypet:=Validated.tend