···11+type error =
22+ | Unexpected_kind of
33+ { expected : Kind.t
44+ ; given : Kind.t
55+ ; repr : Repr.t
66+ }
77+88+type ('a, 'b) t =
99+ { kind : Kind.t
1010+ ; validation : 'a -> ('b, error) Result.t
1111+ }
1212+1313+type 'a v = (Repr.t, 'a) t
1414+1515+let map f v =
1616+ let validation x = x |> v.validation |> Result.map f in
1717+ { v with validation }
1818+;;
1919+2020+let mk ~kind validation = { kind; validation }
2121+2222+let unexpected_kind ~expected ~repr =
2323+ let given = Kind.from_repr repr in
2424+ Unexpected_kind { expected; given; repr } |> Result.error
2525+;;
2626+2727+let or_ a b =
2828+ let expected = Kind.or_ a.kind b.kind in
2929+ let validation x =
3030+ match a.validation x with
3131+ | Ok x -> Ok x
3232+ | _ -> b.validation x
3333+ in
3434+ mk ~kind:expected validation
3535+;;
3636+3737+let null =
3838+ let expected = Kind.null in
3939+ let validation = function
4040+ | Repr.Null -> Ok ()
4141+ | repr -> unexpected_kind ~expected ~repr
4242+ in
4343+ mk ~kind:expected validation
4444+;;
4545+4646+let unit =
4747+ let expected = Kind.unit in
4848+ let validation = function
4949+ | Repr.Unit -> Ok ()
5050+ | repr -> unexpected_kind ~expected ~repr
5151+ in
5252+ mk ~kind:expected validation
5353+;;
+23
lib/pidgin/check.mli
···11+(** Represent a validation function. *)
22+33+(** {1 Types} *)
44+55+type ('a, 'b) t
66+type 'a v = (Repr.t, 'a) t
77+88+type error = private
99+ | Unexpected_kind of
1010+ { expected : Kind.t
1111+ ; given : Kind.t
1212+ ; repr : Repr.t
1313+ }
1414+1515+(** {1 Combining checks} *)
1616+1717+val or_ : ('a, 'b) t -> ('a, 'b) t -> ('a, 'b) t
1818+val map : ('a -> 'b) -> ('input, 'a) t -> ('input, 'b) t
1919+2020+(** {1 Presaved combinators} *)
2121+2222+val unit : unit v
2323+val null : unit v