12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049(** Provides generic signatures for container data structures.
These signatures include functions ([iter], [fold], [exists], [for_all], ...) that you
would expect to find in any container. Used by including [Container.S0] or
[Container.S1] in the signature for every container-like data structure ([Array],
[List], [String], ...) to ensure a consistent interface. *)open!Importopenstruct(*_ If we just bind these aliases directly, without the [open struct ... end], then mdx
sometimes gets confused by seeing these aliases to constructors and prints e.g.
[Base.Container_intf.Option.Some] instead of [Some] *)moduleEither=Either0moduleOption=Option0moduleResult=Result0end[%%template[@@@kind_set.definebase_or_null_with_ext=(base_or_null,value_or_nullmodexternal64)]moduleDefinitions=structmoduleExport=struct(** [Continue_or_stop.t] is used by the [f] argument to [fold_until] in order to
indicate whether folding should continue, or stop early.
@canonical Base.Container.Continue_or_stop *)moduleContinue_or_stop=structtype('a:ka,'b:kb)t=|Continueof'a|Stopof'b[@@kindka=base_or_null,kb=base_or_null]endendincludeExport(** @canonical Base.Container.Summable *)moduletypeSummable=sigtypet:k(** The result of summing no values. *)valzero:t(** An operation that combines two [t]'s and handles [zero + x] by just returning [x],
as well as in the symmetric case. *)val(+):t@m->t@m->t@mend[@@kindk=(base_or_null,value&value,value&value&value,value&value&value&value)][@@modem=(global,local)]moduletypeGeneric_types=sig[@@@kind.defaultk=ks][@@@kindk=kmodseparable](** A [('a, 'p1, 'p2) t] represents a container whose elements are ['a elt]s. ['p1]
and ['p2] are available for extra phantom types a container may track; for
example, the ['key] type of a [Core.Hash_queue]. *)type('a:k,_,_)t(** ['a elt] abstracts over monomorphic and polymorphic containers. In polymorphic
containers like ['a list], we substitute ['a elt := 'a] (see [S1] and friends
below); In monomorphic containers like [string], we substitute ['a elt] with the
element type (e.g. [char]; see [S0] and friends below). *)type('a:k)elt:kend[@@kind_set.explicit_plus_unmangledks=(value,value_or_null,valuemodexternal64,value_or_nullmodexternal64non_float,base,base_or_null_with_ext)]includestruct[@@@alloca@m=(heap_global,stack_local)](*_ We template the following interfaces over the set of kinds that are allowed in the
container [t]. Each such kind set has an associated set of kinds allowed in types
that appear as function arguments/returns but are not put into [t]. For example, a
container that only allows [value mod external64]s can easily still implement
[fold] with a [value] accumulator.
Because the functions with three type variables ([fold_until] and [partition_map])
are rarely needed and are very expensive to generate for the entire cubic space of
possible kinds, we also additionally restrict the [ks] and [ks_not_in_t] for the
cubic functions specifically.
*)[@@@kind_set(ks,ks_not_in_t,ks_for_3,ks_not_in_t_for_3)=((value,value,value,value),(value_or_null,value_or_null,value_or_null,value_or_null),(valuemodexternal64,value,valuemodexternal64,value),(value_or_nullmodexternal64non_float,value_or_null,value_or_nullmodexternal64non_float,value_or_null),(base_or_null_with_ext,base_or_null,value_or_null,value_or_null))]includestruct[@@@alloc.defaulta][@@@kind_set.default.explicit_plus_unmangledks]moduletypeGeneric_without_mem=sigincludeGeneric_types[@kind_set.explicitks]type('a:k1,'b,'c)t:=(('a,'b,'c)t[@kindk1])[@@kind.explicitk1=ks]type('a:k1)elt:k1:=('aelt[@kindk1])[@@kind.explicitk1=ks]includesig(*_ Here, we use [default_if_multiple] because this interface:
(1) Sometimes uses [ks] to represent a single kind that we eventually would
make an abstract kind
(2) Sometimes uses [ks] to represent a "universe" of kinds that the
interface broadly understands and supports all combinations of (which we
eventually will replace with layout polymorphism)
In case (1), there is only one version of each function, so we don't
actually want to mangle it over [k = ks] (because it's silly for users of
e.g. [imm_array] to have to call [(length [@kind immediate64])] to compute
the length of their array).
In case (2), since there are many versions of each function, we mangle the
functions. *)[@@@kind.default_if_multiplek1'=ks][@@@kindk1=k1'modseparable]type('a:k1,'b,'c)t:=(('a,'b,'c)t[@kind.explicitk1'])[@@kindvalue]type('a:k1)elt:k1:=('aelt[@kind.explicitk1'])[@@kindvalue]vallength:('a:k1)'p1'p2.('a,'p1,'p2)t@m->intvalis_empty:('a:k1)'p1'p2.('a,'p1,'p2)t@m->bool(** [iter] must allow exceptions raised in [f] to escape, terminating the
iteration cleanly. The same holds for all functions below taking an [f]. *)valiter:('a:k1)'p1'p2.('a,'p1,'p2)t@m->f:('aelt@m->unit)@local->unit[@@modem=(global,m)](** Returns [true] if and only if there exists an element for which the provided
function evaluates to [true]. This is a short-circuiting operation. *)valexists:('a:k1)'p1'p2.('a,'p1,'p2)t@m->f:('aelt@m->bool)@local->bool[@@modem=(global,m)](** Returns [true] if and only if the provided function evaluates to [true] for
all elements. This is a short-circuiting operation. *)valfor_all:('a:k1)'p1'p2.('a,'p1,'p2)t@m->f:('aelt@m->bool)@local->bool[@@modem=(global,m)](** Returns the number of elements for which the provided function evaluates to
true. *)valcount:('a:k1)'p1'p2.('a,'p1,'p2)t@m->f:('aelt@m->bool)@local->int[@@modem=(global,m)](** Returns as an [option] the first element for which [f] evaluates to true. *)valfind:('a:k1)'p1'p2.('a,'p1,'p2)t@m->f:('aelt@m->bool)@local->('aeltOption.t[@kindk1'orvalue_or_null])@m[@@modem=(global,m)]valto_list:('a:k1)'p1'p2.('a,'p1,'p2)t@m->('aeltList0.Constructors.t[@kindk1'orvalue_or_null])@m[@@alloc__@m=(heap_global,a@m)](** Returns a min (resp. max) element from the collection using the provided
[compare] function. In case of a tie, the first element encountered while
traversing the collection is returned. The implementation uses [fold] so it
has the same complexity as [fold]. Returns [None] iff the collection is
empty. *)valmin_elt:('a:k1)'p1'p2.('a,'p1,'p2)t@m->compare:('aelt@m->'aelt@m->int)@local->('aeltOption.t[@kindk1'orvalue_or_null])@m[@@modem=(global,m)]valmax_elt:('a:k1)'p1'p2.('a,'p1,'p2)t@m->compare:('aelt@m->'aelt@m->int)@local->('aeltOption.t[@kindk1'orvalue_or_null])@m[@@modem=(global,m)][@@@kind.default_if_multiplek2=ks_not_in_t](** Returns the sum of [f i] for all [i] in the container. The order in which
the elements will be summed is unspecified. *)valsum:('a:k1)('sum:k2)'p1'p2.((moduleSummablewithtypet='sum)[@modemo][@kindk2orvalue_or_null])->('a,'p1,'p2)t@mi->f:('aelt@mi->'sum@mo)@local->'sum@mo[@@modemi=(global,m),mo=(global,m)](** [iter_until t ~f ~finish] is a short-circuiting version of [iter]. If [f]
returns [Stop x] the computation ceases and returns [x]. If [f] always
returns [Continue ()] the final result is computed by [finish]. *)valiter_until:('a:k1)'p1'p2('final:k2).('a,'p1,'p2)t@mi->f:('aelt@mi->((unit,'final)Continue_or_stop.t[@kindvalue_or_null(k2orvalue_or_null)])@mo)@local->finish:(unit->'final@mo)@local->'final@mo[@@modemi=(global,m),mo=(global,m)](** [fold t ~init ~f] returns [f (... f (f (f init e1) e2) e3 ...) en], where
[e1..en] are the elements of [t]. *)valfold:('a:k1)'p1'p2('acc:k2).('a,'p1,'p2)t@mi->init:'acc@mo->f:('acc@mo->'aelt@mi->'acc@mo)@local->'acc@mo[@@modemi=(global,m),mo=(global,m)](** [fold_result t ~init ~f] is a short-circuiting version of [fold] that runs
in the [Result] monad. If [f] returns an [Error _], that value is returned
without any additional invocations of [f]. *)valfold_result:('a:k1)'p1'p2('acc:k2)'e.('a,'p1,'p2)t@mi->init:'acc@mo->f:('acc@mo->'aelt@mi->(('acc,'e)Result.t[@kindk2orvalue_or_null])@mo)@local->(('acc,'e)Result.t[@kindk2orvalue_or_null])@mo[@@modemi=(global,m),mo=(global,m)](** Returns the first evaluation of [f] that returns [Some], and returns [None]
if there is no such element. *)valfind_map:('a:k1)'p1'p2('b:k2).('a,'p1,'p2)t@mi->f:('aelt@mi->('bOption.t[@kindk2orvalue_or_null])@mo)@local->('bOption.t[@kindk2orvalue_or_null])@mo[@@modemi=(global,m),mo=(global,m)]endincludesig[@@@kind.default_if_multiplek1'=ks_for_3][@@@kindk1=k1'modseparable]type('a:k1,'b,'c)t:=(('a,'b,'c)t[@kind.explicitk1'])[@@kindvalue]type('a:k1)elt:k1:=('aelt[@kind.explicitk1'])[@@kindvalue][@@@kind.default_if_multiplek2=ks_not_in_t_for_3][@@@kind.default_if_multiplek3=ks_not_in_t_for_3](** [fold_until t ~init ~f ~finish] is a short-circuiting version of [fold]. If
[f] returns [Stop _] the computation ceases and results in that value. If
[f] returns [Continue _], the fold will proceed. If [f] never returns
[Stop _], the final result is computed by [finish].
Example:
{[
type maybe_negative =
| Found_negative of int
| All_nonnegative of { sum : int }
(** [first_neg_or_sum list] returns the first negative number in [list], if any,
otherwise returns the sum of the list. *)
let first_neg_or_sum =
List.fold_until ~init:0
~f:(fun sum x ->
if x < 0
then Stop (Found_negative x)
else Continue (sum + x))
~finish:(fun sum -> All_nonnegative { sum })
;;
let x = first_neg_or_sum [1; 2; 3; 4; 5]
val x : maybe_negative = All_nonnegative {sum = 15}
let y = first_neg_or_sum [1; 2; -3; 4; 5]
val y : maybe_negative = Found_negative -3
]} *)valfold_until:('a:k1)'p1'p2('acc:k2)('final:k3).('a,'p1,'p2)t@mi->init:'acc@mo->f:('acc@mo->'aelt@mi->(('acc,'final)Continue_or_stop.t[@kind(k2orvalue_or_null)(k3orvalue_or_null)])@mo)@local->finish:('acc@mo->'final@mo)@local->'final@mo[@@modemi=(global,m),mo=(global,m)]endendmoduletypeGeneric=sigincludeGeneric_without_mem[@kind_set.explicitks][@alloca][@@@kind.default_if_multiplek'=ks][@@@kindk=k'modseparable](** Checks whether the provided element is there, using [equal]. *)valmem:('a:k)'p1'p2.(('a,'p1,'p2)t[@kindk'])@m->('aelt[@kindk'])@m->equal:(('aelt[@kindk'])@m->('aelt[@kindk'])@m->bool)@local->bool[@@modem=(global,m)]end(** Like [Generic], but [mem] does not accept an [equal] function, since [Make0]
already takes [Elt.equal]. *)moduletypeGeneric_for_s0=sigincludeGeneric_without_mem[@kind_set.explicitks][@alloca][@@@kind.default_if_multiplek'=ks][@@@kindk=k'modseparable](** Checks whether the provided element is there, using equality on [elt]s. *)valmem:(('a,_,_)t[@kindk'])@m->('aelt[@kindk'])@m->bool[@@modem=(global,m)]endendendincludestruct[@@@alloc.defaulta@m=(heap_global,stack_local)]moduletypeGeneric=sigincludeGeneric[@kind_set.explicitks][@alloca](*_ This doesn't have a local version because arrays can't hold local values. *)valto_array:('a,_,_)t->'aeltarrayend[@@kind_setks=value](** Signature for monomorphic container - a container for a specific element type,
e.g., string, which is a container of characters ([type elt = char]) and never of
anything else. *)moduletype[@kind_set.explicit_plus_unmangledks=(value,value_or_null,valuemodexternal64,base_or_null_with_ext)]S0=sigincludesig[@@@kind.defaultk'=ks][@@@kindk=k'modseparable]typettypeelt:kendincludeGeneric_for_s0[@kind_set.explicitks][@alloca][@with:[@@@kind.defaultk'=ks][@@@kindk=k'modseparable]type(_:k,_,_)t:=(t[@kindk'])type(_:k)elt:=(elt[@kindk'])][@@@kind.default_if_multiplek=ks](*_ This doesn't have a local version because arrays can't hold local values. *)valto_array:(t[@kindk])->(elt[@kindk])arrayendmoduletype[@kind_set.explicit_plus_unmangledks=(value,value_or_null,valuemodexternal64,base_or_null_with_ext)]S0_phantom=sigincludesig[@@@kind.defaultk'=ks][@@@kindk=k'modseparable]typeelt:ktype'phantomtendincludeGeneric_for_s0[@kind_set.explicitks][@alloca][@with:[@@@kind.defaultk'=ks][@@@kindk=k'modseparable]type(_:k,'phantom,_)t:=('phantomt[@kindk'])type(_:k)elt:=(elt[@kindk'])][@@@kind.default_if_multiplek=ks](*_ This doesn't have a local version because arrays can't hold local values. *)valto_array:(_t[@kindk])->(elt[@kindk])arrayendendincludestruct[@@@alloca@m=(heap_global,stack_local)](*_ See the explanation of [ks_for_3] above *)[@@@kind_set(ks,ks_for_3)=((value,value),(value_or_null,value_or_null),(valuemodexternal64,valuemodexternal64),(value_or_nullmodexternal64non_float,value_or_nullmodexternal64non_float),(base_or_null_with_ext,value_or_null))]includestruct[@@@alloc.defaulta][@@@kind_set.default.explicit_plus_unmangledks](** Signature for polymorphic container, e.g., ['a list] or ['a array]. *)moduletypeS1=sigtype('a:kmodseparable)t[@@kindk=ks]includeGeneric[@kind_set.explicitks][@alloca][@with:[@@@kind.defaultk'=ks][@@@kindk=k'modseparable]type('a:k,_,_)t:=('at[@kindk'])type('a:k)elt:='a][@@@kind.default_if_multiplek=ks](*_ This doesn't have a local version because arrays can't hold local values. *)valto_array:('a:kmodseparable).('at[@kindk])->'aarrayendmoduletypeS1_phantom=sigtype('a:kmodseparable,'phantom)t[@@kindk=ks]includeGeneric[@kind_set.explicitks][@alloca][@with:[@@@kind.defaultk'=ks][@@@kindk=k'modseparable]type('a:k,'phantom,_)t:=(('a,'phantom)t[@kindk'])type('a:k)elt:='a][@@@kind.default_if_multiplek=ks](*_ This doesn't have a local version because arrays can't hold local values. *)valto_array:('a:kmodseparable)'p.(('a,'p)t[@kindk])->'aarrayendmoduletypeCreators=sigincludeGeneric_types[@kind_set.explicitks]type('a:k1,'b,'c)t:=(('a,'b,'c)t[@kindk1])[@@kind.explicitk1=ks]type('a:k1)elt:k1:=('aelt[@kindk1])[@@kind.explicitk1=ks]type(_,_,_)concatincludesig[@@@kind.default_if_multiplek1'=ks][@@@kindk1=k1'modseparable]type('a:k1,'b,'c)t:=(('a,'b,'c)t[@kind.explicitk1'])[@@kindvalue]type('a:k1)elt:k1:=('aelt[@kind.explicitk1'])[@@kindvalue]valof_list:('a:k1)'p1'p2.('aeltList0.Constructors.t[@kindk1'orvalue_or_null])@m->('a,'p1,'p2)t@m[@@alloc__@m=(heap_global,a@m)](** E.g., [append (of_list [a; b]) (of_list [c; d; e])] is
[of_list [a; b; c; d; e]] *)valappend:('a:k1)'p1'p2.('a,'p1,'p2)t@m->('a,'p1,'p2)t@m->('a,'p1,'p2)t@m[@@alloc__@m=(heap_global,a@m)](** Concatenates a nested container. The elements of the inner containers are
concatenated together in order to give the result. *)valconcat:('a:k1)'p1'p2.(('a,'p1,'p2)t,'p1,'p2)concat@m->('a,'p1,'p2)t@m[@@alloc__@m=(heap_global,a@m)](** [filter t ~f] returns all the elements of [t] that satisfy the predicate
[f]. *)valfilter:('a:k1)'p1'p2.('a,'p1,'p2)t@m->f:('aelt@m->bool)@local->('a,'p1,'p2)t@m[@@alloc__@m=(heap_global,a@m)](** [partition_tf t ~f] returns a pair [t1, t2], where [t1] is all elements of
[t] that satisfy [f], and [t2] is all elements of [t] that do not satisfy
[f]. The "tf" suffix is mnemonic to remind readers that the result is
(trues, falses). *)valpartition_tf:('a:k1)'p1'p2.('a,'p1,'p2)t@m->f:('aelt@m->bool)@local->('a,'p1,'p2)t*('a,'p1,'p2)t@m[@@alloc__@m=(heap_global,a@m)]endincludesig[@@@kind.default_if_multiplek1'=ks][@@@kind.default_if_multiplek2'=ks][@@@kindk1=k1'modseparable,k2=k2'modseparable](** [map f (of_list [a1; ...; an])] applies [f] to [a1], [a2], ..., [an], in
order, and builds a result equivalent to [of_list [f a1; ...; f an]]. *)valmap:('a:k1)'p1'p2('b:k2).(('a,'p1,'p2)t[@kindk1'])@mi->f:(('aelt[@kindk1'])@mi->('belt[@kindk2'])@mo)@local->(('b,'p1,'p2)t[@kindk2'])@mo[@@modemi=(global,m)][@@alloc__@mo=(heap_global,a@m)](** [filter_map t ~f] applies [f] to every [x] in [t]. The result contains every
[y] for which [f x] returns [Some y]. *)valfilter_map:('a:k1)'p1'p2('b:k2).(('a,'p1,'p2)t[@kindk1'])@mi->f:(('aelt[@kindk1'])@mi->(('belt[@kindk2'])Option.t[@kindk2'orvalue_or_null])@mo)@local->(('b,'p1,'p2)t[@kindk2'])@mo[@@modemi=(global,m)][@@alloc__@mo=(heap_global,a@m)](** [concat_map t ~f] is equivalent to [concat (map t ~f)]. *)valconcat_map:('a:k1)'p1'p2('b:k2).(('a,'p1,'p2)t[@kindk1'])@mi->f:(('aelt[@kindk1'])@mi->(('b,'p1,'p2)t[@kindk2'])@mo)@local->(('b,'p1,'p2)t[@kindk2'])@mo[@@modemi=(global,m)][@@alloca@mo=(heap_global,a@m)]endincludesig[@@@kind.default_if_multiplek1'=ks_for_3][@@@kind.default_if_multiplek2'=ks_for_3][@@@kind.default_if_multiplek3'=ks_for_3][@@@kindk1=k1'modseparable,k2=k2'modseparable,k3=k3'modseparable](** [partition_map t ~f] partitions [t] according to [f]. *)valpartition_map:('a:k1)'p1'p2('b:k2)('c:k3).(('a,'p1,'p2)t[@kindk1'])@mi->f:(('aelt[@kindk1'])@mi->((('belt[@kindk2']),('celt[@kindk3']))Either.t[@kind(k2'orvalue_or_null)(k3'orvalue_or_null)])@mo)@local->(('b,'p1,'p2)t[@kindk2'])*(('c,'p1,'p2)t[@kindk3'])@mo[@@modemi=(global,m)][@@alloc__@mo=(heap_global,a@m)]endendmoduletypeGeneric_with_creators=sigincludeGeneric[@kind_set.explicitks][@alloca]includeCreators[@kind_set.explicitks][@alloca][@with:[@@@kind.defaultk'=ks][@@@kindk=k'modseparable]type('a:k,'b,'c)t:=(('a,'b,'c)t[@kindk'])type('a:k)elt:=('aelt[@kindk'])]end(** Like [Generic_with_creators], but [mem] does not accept an [equal] function,
since [Make0_with_creators] already takes [Elt.equal]. *)moduletypeGeneric_with_creators_for_s0=sigincludeGeneric_for_s0[@kind_set.explicitks][@alloca]includeCreators[@kind_set.explicitks][@alloca][@with:[@@@kind.defaultk'=ks][@@@kindk=k'modseparable]type('a:k,'b,'c)t:=(('a,'b,'c)t[@kindk'])type('a:k)elt:=('aelt[@kindk'])]endendendincludestruct[@@@alloc.defaulta@m=(heap_global,stack_local)]moduletypeGeneric_with_creators=sigincludeGeneric_with_creators[@kind_set.explicitks][@alloca](*_ This doesn't have a local version because arrays can't hold local values. *)valto_array:('a,_,_)t->'aeltarrayvalof_array:'aeltarray@m->('a,_,_)t@m[@@alloc__@m=(heap_global,a@m)]end[@@kind_setks=value]includestruct[@@@alloc.defaulta](*_ This is outside the template because an [immediate] container can't contain
itself *)moduletype[@kind_set.explicit_plus_unmangledks=(value,base_or_null_with_ext)]S0_with_creators=sigincludesig[@@@kind.defaultk'=ks][@@@kindk=k'modseparable]typettypeelt:kendincludeGeneric_with_creators_for_s0[@kind_set.explicitks][@alloca][@with:type(_,_,_)concat:=tlist[@@@kind.defaultk'=ks][@@@kindk=k'modseparable]type('a:k,_,_)t:=(t[@kindk'])type(_:k)elt:=(elt[@kindk'])][@@@kind.default_if_multiplek=ks](*_ This doesn't have a local version because arrays can't hold local values. *)valto_array:(t[@kindk])->(elt[@kindk])arrayvalof_array:(elt[@kindk])array@m->(t[@kindk])@m[@@alloc__@m=(heap_global,a@m)]endend[@@@kind_setks=(value,value_or_null,base_or_null_with_ext)]includestruct[@@@alloc.defaulta][@@@kind_set.default.explicit_plus_unmangledks]moduletypeS1_with_creators=sigtype('a:kmodseparable)t[@@kindk=ks]includeGeneric_with_creators[@kind_set.explicitks][@alloca][@with:type('a,_,_)concat:='at[@@@kind.defaultk'=ks][@@@kindk=k'modseparable]type('a:k,_,_)t:=('at[@kindk'])type('a:k)elt:='a][@@@kind.default_if_multiplek=ks](*_ This doesn't have a local version because arrays can't hold local values. *)valto_array:('a:kmodseparable).('at[@kindk])->'aarrayvalof_array:('a:kmodseparable).'aarray@m->('at[@kindk])@m[@@alloc__@m=(heap_global,a@m)]endendendtype('t,'a:any,'acc:any)fold='t@mi->init:'acc@mo->f:('acc@mo->'a@mi->'acc@mo)@local->'acc@mo[@@modemi=(global,local),mo=(global,local)]type('t,'a:any,'acc:any,'final:any)fold_until='t@mi->init:'acc@mo->f:('acc@mo->'a@mi->('acc,'final)Continue_or_stop.t@mo)@local->finish:('acc@mo->'final@mo)@local->'final@mo[@@modemi=(global,local),mo=(global,local)]type('t,'a:any)iter='t@m->f:('a@m->unit)@local->unit[@@modem=(global,local)]type('t,'a:any,'final:any)iter_until='t@mi->f:('a@mi->(unit,'final)Continue_or_stop.t@mo)@local->finish:(unit->'final@mo)@local->'final@mo[@@modemi=(global,local),mo=(global,local)]type'tlength='t@m->int[@@modem=(global,local)]moduletypeMake_gen_arg=sigtype('a,'phantom1,'phantom2)ttype'aeltvalfold_until:((('a,_,_)t,'aelt,'acc,'final)fold_until[@modemimo])[@@modemi=(global,m),mo=(global,m)]valfold:[`Define_using_fold_until|`Customof((('a,_,_)t,'aelt,'acc)fold[@modemimo])][@@modemi=(global,m),mo=(global,m)]valiter_until:[`Define_using_fold_until|`Customof((('a,_,_)t,'aelt,'final)iter_until[@modemimo])][@@modemi=(global,m),mo=(global,m)](** The [iter] argument to [Container.Make] specifies how to implement the container's
[iter] function. [`Define_using_fold] means to define [iter] via:
{[
iter t ~f = Container.iter ~fold t ~f
]}
[`Custom] overrides the default implementation, presumably with something more
efficient. Several other functions returned by [Container.Make] are defined in
terms of [iter], so passing in a more efficient [iter] will improve their
efficiency as well. *)valiter:[`Define_using_fold|`Define_using_iter_until|`Customof((('a,_,_)t,'aelt)iter[@modem])][@@modem=(global,m)](** The [length] argument to [Container.Make] specifies how to implement the
container's [length] function. [`Define_using_fold] means to define [length] via:
{[
length t ~f = Container.length ~fold t ~f
]}
[`Custom] overrides the default implementation, presumably with something more
efficient. Several other functions returned by [Container.Make] are defined in
terms of [length], so passing in a more efficient [length] will improve their
efficiency as well. *)vallength:[`Define_using_fold|`Customof(('a,_,_)tlength[@modem])]end[@@modem=(global,local)]moduletypeMake_arg=sigtype'atincludeMake_gen_arg[@modem]withtype('a,_,_)t:='atandtype'aelt:='aend[@@modem=(global,local)]moduletypeMake0_arg=sigmoduleElt:sigtypetvalequal:t@m->t@m->bool[@@modem=(global,m)]endtypetincludeMake_gen_arg[@modem]withtype('a,_,_)t:=tandtype'aelt:=Elt.tend[@@modem=(global,local)]moduletypeMake_common_with_creators_arg=sigincludeMake_gen_argtype(_,_,_)concatvalof_list:'aeltlist->('a,_,_)tvalof_array:'aeltarray->('a,_,_)tvalconcat:(('a,_,_)t,_,_)concat->('a,_,_)tendmoduletypeMake_gen_with_creators_arg=sigincludeMake_common_with_creators_argvalconcat_of_array:'aarray->('a,_,_)concatendmoduletypeMake_with_creators_arg=sigtype'atincludeMake_common_with_creators_argwithtype('a,_,_)t:='atandtype'aelt:='aandtype('a,_,_)concat:='atendmoduletypeMake0_with_creators_arg=sigmoduleElt:sigtypetvalequal:t->t->boolendtypetincludeMake_common_with_creators_argwithtype('a,_,_)t:=tandtype'aelt:=Elt.tandtype('a,_,_)concat:='alistendmoduletype[@kind.explicitk=(value,value_or_null)]Derived=sigincludesig[@@@mode.defaultm=(global,local)](** Generic defintions that rely on [With_return] and therefore don't support local
return values. *)valfold_until:'t('a:k)('acc:k)('final:k).fold:(('t,'a,'acc)fold[@modemglobal])->(('t,'a,'acc,'final)fold_until[@modemglobal])(** Generic definitions of container operations in terms of [fold].
E.g.: [iter ~fold t ~f = fold t ~init:() ~f:(fun () a -> f a)]. *)valiter_via_fold:'t('a:k).fold:(('t,'a,unit)fold[@modemglobal])->(('t,'a)iter[@modem])valcount:'t('a:k).fold:(('t,'a,int)fold[@modemglobal])->'t@m->f:('a@m->bool)@local->intvalmin_elt:'t('a:k).fold:(('t,'a,'aoption)fold[@modemm])->'t@m->compare:('a@m->'a@m->int)@local->'aoption@mvalmax_elt:'t('a:k).fold:(('t,'a,'aoption)fold[@modemm])->'t@m->compare:('a@m->'a@m->int)@local->'aoption@mvallength:'t('a:k).fold:(('t,'a,int)fold[@modemglobal])->('tlength[@modem])endvalto_list:'t('a:k).fold:(('t,'a,'alist)fold[@modemm])->'t@m->'alist@m[@@alloc__@m=(heap_global,stack_local)]valsum:'t('a:k)('sum:k).fold:(('t,'a,'sum)fold[@modemimo])->((moduleSummablewithtypet='sum)[@kindkorvalue_or_null][@modemo])->'t@mi->f:('a@mi->'sum@mo)@local->'sum@mo[@@modemi=(global,local),mo=(global,local)](** Generic definitions of container operations in terms of [fold_until]. *)valfold:'t('a:k)('acc:k).fold_until:(('t,'a,'acc,'acc)fold_until[@modemimo])->(('t,'a,'acc)fold[@modemimo])[@@modemi=(global,local),mo=(global,local)]valfold_result:'t('a:k)('acc:k)'e.fold_until:(('t,'a,'acc,('acc,'e)Result.t)fold_until[@modemimo])->'t@mi->init:'acc@mo->f:('acc@mo->'a@mi->('acc,'e)Result.t@mo)@local->('acc,'e)Result.t@mo[@@modemi=(global,local),mo=(global,local)]valiter_until:'t('a:k)('final:k).fold_until:(('t,'a,unit,'final)fold_until[@modemimo])->(('t,'a,'final)iter_until[@modemimo])[@@modemi=(global,local),mo=(global,local)](** Generic definitions of container operations in terms of [iter_until]. *)includesig[@@@mode.defaultm=(global,local)]valiter_via_iter_until:'t('a:k).iter_until:(('t,'a,unit)iter_until[@modemglobal])->(('t,'a)iter[@modem])valis_empty:'t('a:k).iter_until:(('t,'a,bool)iter_until[@modemglobal])->'t@m->boolvalmem:'t('a:k).iter_until:(('t,'a,bool)iter_until[@modemglobal])->'t@m->'a@m->equal:('a@m->'a@m->bool)@local->boolvalexists:'t('a:k).iter_until:(('t,'a,bool)iter_until[@modemglobal])->'t@m->f:('a@m->bool)@local->boolvalfor_all:'t('a:k).iter_until:(('t,'a,bool)iter_until[@modemglobal])->'t@m->f:('a@m->bool)@local->boolvalfind:'t('a:k).iter_until:(('t,'a,'aoption)iter_until[@modemm])->'t@m->f:('a@m->bool)@local->'aoption@mendvalfind_map:'t('a:k)('b:k).iter_until:(('t,'a,'boption)iter_until[@modemimo])->'t@mi->f:('a@mi->'boption@mo)@local->'boption@mo[@@modemi=(global,local),mo=(global,local)](** Generic definitons of container operations in terms of [iter] and [length]. *)valto_array:'t('a:kmodseparable).length:'tlength->iter:('t,'a)iter->'t->'aarrayendendmoduletypeContainer=sig@@portableincludemoduletypeofstructincludeDefinitionsendmodule%templateDerived:Derived[@kind.explicitk][@@kind.explicitk=(value,value_or_null)]includemoduletypeofDerived[@kind.explicitvalue](** The idiom for using [Container.Make] is to bind the resulting module and to
explicitly import each of the functions that one wants:
{[
module C = Container.Make (struct ... end)
let count = C.count
let exists = C.exists
let find = C.find
(* ... *)
]}
This is preferable to:
{[
include Container.Make (struct ... end)
]}
because the [include] makes it too easy to shadow specialized implementations of
container functions ([length] being a common one).
[Container.Make0] is like [Container.Make], but for monomorphic containers like
[string]. *)module%template.portableMake(T:Make_arg[@modem]):S1[@alloca]withtype'at:='aT.t[@@alloca@m=(heap_global,stack_local)]module%template.portableMake0(T:Make0_arg[@modem]):S0[@alloca]withtypet:=T.tandtypeelt:=T.Elt.t[@@alloca@m=(heap_global,stack_local)]module%template.portableMake_gen(T:Make_gen_arg[@modem]):Generic[@alloca]withtype('a,'phantom1,'phantom2)t:=('a,'phantom1,'phantom2)T.tandtype'aelt:='aT.elt[@@alloca@m=(heap_global,stack_local)]module%template.portableMake_with_creators(T:Make_with_creators_arg):S1_with_creators[@allocheap]withtype'at:='aT.tmodule%template.portableMake0_with_creators(T:Make0_with_creators_arg):S0_with_creators[@allocheap]withtypet:=T.tandtypeelt:=T.Elt.tmodule%template.portableMake_gen_with_creators(T:Make_gen_with_creators_arg):Generic_with_creators[@allocheap]withtype('a,'phantom1,'phantom2)t:=('a,'phantom1,'phantom2)T.tandtype'aelt:='aT.eltandtype('a,'phantom1,'phantom2)concat:=('a,'phantom1,'phantom2)T.concatend]