123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197openBasemoduleInterfaces=struct(** A profunctor has an input end with contravariant map, an output
end with covariant map and an operation to join two terms with
the same input type giving both outputs.
*)moduletypeS=sigtype('b,'a)tvalmap:('a,'u)t->f:('a->'b)->('b,'u)tvalcontra_map:('u,'b)t->f:('a->'b)->('u,'a)tvalboth:('a,'i)t->('b,'i)t->('a*'b,'i)tend(** @open *)(** A module used to traverse each field of a record performing some
action using a specific profunctor.
You can construct a record builder for a given profunctor using
{{!module-Profunctor.module-Record_builder}Record_builder}.
This is based on the library {!module-Record_builder}
(which provides traversal with an
{{!modtype:Base.Applicative.S}applicative}) and adds
the contravariant mapping of each field.
{[
type t =
{ name : string
; age : int
}
[@@deriving fields ~iterators:make_creator]
module F : Profunctor.S = "your module here"
module F_of_record = Profunctor.Record_builder (F)
let for_string : (string, string) F.t = "your code here"
let for_int : (int, int) F.t = "your code here"
let example : (t, t) F.t =
F_of_record.(
build_for_record
(Fields.make_creator ~name:(field for_string) ~age:(field for_int)))
;;
]}
This is equivalent to:
{[
let example : (t, t) F.t =
let name = F.contra_map ~f:name for_string
and age = F.contra_map ~f:age for_int in
F.map (F.both name age) ~f:(fun (name, age) -> { name; age })
;;
]}
*)moduletypeRecord_builder=sigtype('b,'a)profunctor(** A term of the profunctor where the input and output type are
the same.
Although this module must use the type parameters separately
internally all terms supplied as arguments or returned will
have both type parameters equal. This type alias is used to
allow automatically converting with some other type in some
cases e.g. {!module-Of_conv_based}.
*)type'aprofunctor_termvalprj:('a,'a)profunctor->'aprofunctor_termvalinj:'aprofunctor_term->('a,'a)profunctor(** The underlying applicative record builder,
which does not perform the contravariant mapping.
*)moduleBare:Record_builder.S2withtype('b,'a)applicative=('b,'a)profunctor(** Supply the term for one field.
The type of this function is designed to match up with [Fields.make_creator]
(see the example).
*)valfield:'fieldprofunctor_term->('record,'field)Field.t->('field,_,_,'record)Bare.Make_creator_types.handle_one_field(** Build the overarching profunctor for the whole record.
This takes a partial application of [Fields.make_creator] as its argument,
which should supply no initial value but use {!field} to supply a term
for every field of the record.
The type of this is designed to match up with [Fields.make_creator]
(see the example).
*)valbuild_for_record:('record,_,'record)Bare.Make_creator_types.handle_all_fields->'recordprofunctor_termend(** A profunctor constructed from an {{!modtype:Base.Applicative.S}applicative}.
In this case [contra_map] has no effect, and [map] and [both]
behave exactly as they would with the underlying applicative.
*)moduletypeOf_applicative=sigtype'aapplicativetype('b,'a)t='bapplicativeincludeSwithtype('b,'a)t:=('b,'a)tmoduleOf_record:Record_builderwithtype'aprofunctor_term='aapplicativeandtype('b,'a)profunctor=('b,'a)tend(** A profunctor-ish where both parameters must be mapped together
at the same time. This is less expressive but appears in
several libraries.
*)moduletypeConv_based=sigtype'atvalconv:'at->('a->'b)->('b->'a)->'btvalboth:'at->'bt->('a*'b)tend(** Embed a {!modtype:Conv_based} profunctor-ish into a full profunctor,
allowing the use of {!modtype:Record_builder} directly.
*)moduletypeOf_conv_based=sigtype'aconv_basedtype('b,'a)tincludeSwithtype('b,'a)t:=('b,'a)tvalinj:'aconv_based->('a,'a)tvalprj:('a,'a)t->'aconv_basedmoduleOf_record:Record_builderwithtype'aprofunctor_term='aconv_basedandtype('b,'a)profunctor=('b,'a)tendendmoduletypeProfunctor=sigincludemoduletypeofInterfaces(** @inline *)moduleRecord_builder(F:S):Record_builderwithtype('b,'a)profunctor=('b,'a)F.tandtype'aprofunctor_term=('a,'a)F.tmoduleOf_applicative(F:Applicative.S):Of_applicativewithtype'aapplicative:='aF.tmoduleOf_conv_based(F:Conv_based):Of_conv_basedwithtype'aconv_based:='aF.t(** A profunctor which represents a function where
[Fn.id] may sometimes be distinguished from other
functions.
This is primarily used internally to implement other
things where discarding identity functions can be advantageous.
*)moduleFn_with_id:sigtype('b,'a)t=|Id:('a,'a)t|Apply:('a->'b)->('b,'a)tincludeSwithtype('b,'a)t:=('b,'a)tvalid:('a,'a)tvalof_fn:('a->'b)->('b,'a)t(** Unpack the function, [as_fn (of_fn x) ≡ Staged.stage x]. *)valas_fn:('b,'a)t->('a->'b)Staged.t(** [split l r ≡ both (contra_map ~f:fst l) (contra_map ~f:snd r)],
but is more efficient (the result may be [Id]).
*)valsplit:('b,'a)t->('d,'c)t->('b*'d,'a*'c)t(** Composition of function, [as_fn (compose g f) ≡ Fn.compose (as_fn g) (as_fn f)]. *)valcompose:('c,'b)t->('b,'a)t->('c,'a)tmoduleOf_record:Record_builderwithtype('b,'a)profunctor=('b,'a)tandtype'aprofunctor_term=('a,'a)tendend