12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097open!ImportopenContainer_intf.ExportmoduleArray=Array0moduleList=List0moduleStep=struct(* 'a is an item in the sequence, 's is the state that will produce the remainder of
the sequence *)type('a,'s)t=|Done|Skipof's|Yieldof'a*'s[@@deriving_inlinesexp_of]letsexp_of_t:typeas.(a->Ppx_sexp_conv_lib.Sexp.t)->(s->Ppx_sexp_conv_lib.Sexp.t)->(a,s)t->Ppx_sexp_conv_lib.Sexp.t=fun_of_a->fun_of_s->function|Done->Ppx_sexp_conv_lib.Sexp.Atom"Done"|Skipv0->letv0=_of_sv0inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Skip";v0]|Yield(v0,v1)->letv0=_of_av0andv1=_of_sv1inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Yield";v0;v1][@@@end]endopenStep(* 'a is an item in the sequence, 's is the state that will produce the remainder of the
sequence *)type+_t=|Sequence:'s*('s->('a,'s)Step.t)->'attype'asequence='atmoduleExpert=structletnext_step(Sequence(s,f))=matchfswith|Done->Done|Skips->Skip(Sequence(s,f))|Yield(a,s)->Yield(a,Sequence(s,f));;letdelayed_fold_steps~init~f~finish=letrecloopsnextfinishfacc=matchnextswith|Done->finishacc|Skips->faccNone~k:(loopsnextfinishf)|Yield(a,s)->facc(Somea)~k:(loopsnextfinishf)inmatchswith|Sequence(s,next)->loopsnextfinishfinit;;endletunfold_step~init~f=Sequence(init,f)letunfold~init~f=unfold_step~init~f:(funs->matchfswith|None->Step.Done|Some(a,s)->Step.Yield(a,s))letunfold_withs~init~f=matchswith|Sequence(s,next)->Sequence((init,s),(fun(seed,s)->matchnextswith|Done->Done|Skips->Skip(seed,s)|Yield(a,s)->matchfseedawith|Done->Done|Skipseed->Skip(seed,s)|Yield(a,seed)->Yield(a,(seed,s))))letunfold_with_and_finishs~init~running_step~inner_finished~finishing_step=matchswith|Sequence(s,next)->Sequence(`Inner_running(init,s),(funstate->matchstatewith|`Inner_running(state,inner_state)->beginmatchnextinner_statewith|Done->Skip(`Inner_finished(inner_finishedstate))|Skipinner_state->Skip(`Inner_running(state,inner_state))|Yield(x,inner_state)->matchrunning_stepstatexwith|Done->Done|Skipstate->Skip(`Inner_running(state,inner_state))|Yield(y,state)->Yield(y,`Inner_running(state,inner_state))end|`Inner_finishedstate->beginmatchfinishing_stepstatewith|Done->Done|Skipstate->Skip(`Inner_finishedstate)|Yield(y,state)->Yield(y,`Inner_finishedstate)end))letof_listl=unfold_step~init:l~f:(function|[]->Done|x::l->Yield(x,l))letfoldt~init~f=letrecloopseedvnextf=matchnextseedwith|Done->v|Skips->loopsvnextf|Yield(a,s)->loops(fva)nextfinmatchtwith|Sequence(seed,next)->loopseedinitnextfletto_list_revt=foldt~init:[]~f:(funlx->x::l)letto_list(Sequence(s,next))=letsafe_to_listt=List.rev(to_list_revt)inletrecto_listsnexti=ifi=0thensafe_to_list(Sequence(s,next))elsematchnextswith|Done->[]|Skips->to_listsnexti|Yield(a,s)->a::(to_listsnext(i-1))into_listsnext500letsexp_of_tsexp_of_at=sexp_of_listsexp_of_a(to_listt)letrange?(stride=1)?(start=`inclusive)?(stop=`exclusive)start_vstop_v=letstep=matchstopwith|`inclusivewhenstride>=0->funi->ifi>stop_vthenDoneelseYield(i,i+stride)|`inclusive->funi->ifi<stop_vthenDoneelseYield(i,i+stride)|`exclusivewhenstride>=0->funi->ifi>=stop_vthenDoneelseYield(i,i+stride)|`exclusive->funi->ifi<=stop_vthenDoneelseYield(i,i+stride)inletinit=matchstartwith|`inclusive->start_v|`exclusive->start_v+strideinunfold_step~init~f:stepletof_lazyt_lazy=unfold_step~init:t_lazy~f:(funt_lazy->letSequence(s,next)=Lazy.forcet_lazyinmatchnextswith|Done->Done|Skips->Skip(letv=Sequence(s,next)inlazyv)|Yield(x,s)->Yield(x,letv=Sequence(s,next)inlazyv))letmapt~f=matchtwith|Sequence(seed,next)->Sequence(seed,funseed->matchnextseedwith|Done->Done|Skips->Skips|Yield(a,s)->Yield(fa,s))letmapit~f=matchtwith|Sequence(s,next)->Sequence((0,s),fun(i,s)->matchnextswith|Done->Done|Skips->Skip(i,s)|Yield(a,s)->Yield(fia,(i+1,s)))letfolding_mapt~init~f=unfold_witht~init~f:(funaccx->letacc,x=faccxinYield(x,acc))letfolding_mapit~init~f=unfold_witht~init:(0,init)~f:(fun(i,acc)x->letacc,x=fiaccxinYield(x,(i+1,acc)))letfiltert~f=matchtwith|Sequence(seed,next)->Sequence(seed,funseed->matchnextseedwith|Done->Done|Skips->Skips|Yield(a,s)whenfa->Yield(a,s)|Yield(_,s)->Skips)letfilterit~f=map~f:snd(filter(mapit~f:(funis->(i,s)))~f:(fun(i,s)->fis))letlengtht=letrecloopisnext=matchnextswith|Done->i|Skips->loopisnext|Yield(_,s)->loop(i+1)snextinmatchtwith|Sequence(seed,next)->loop0seednextletto_list_rev_with_lengtht=foldt~init:([],0)~f:(fun(l,i)x->(x::l,i+1))letto_arrayt=let(l,len)=to_list_rev_with_lengthtinmatchlwith|[]->[||]|x::l->leta=Array.create~lenxinletrecloopil=matchlwith|[]->assert(i=-1)|x::l->a.(i)<-x;loop(i-1)linloop(len-2)l;aletfindt~f=letrecloopsnextf=matchnextswith|Done->None|Yield(a,_)whenfa->Somea|Yield(_,s)|Skips->loopsnextfinmatchtwith|Sequence(seed,next)->loopseednextfletfind_mapt~f=letrecloopsnextf=matchnextswith|Done->None|Yield(a,s)->(matchfawith|None->loopsnextf|some_b->some_b)|Skips->loopsnextfinmatchtwith|Sequence(seed,next)->loopseednextfletfind_mapit~f=letrecloopsnextfi=matchnextswith|Done->None|Yield(a,s)->(matchfiawith|None->loopsnextf(i+1)|some_b->some_b)|Skips->loopsnextfiinmatchtwith|Sequence(seed,next)->loopseednextf0letfor_allt~f=letrecloopsnextf=matchnextswith|Done->true|Yield(a,_)whennot(fa)->false|Yield(_,s)|Skips->loopsnextfinmatchtwith|Sequence(seed,next)->loopseednextfletfor_allit~f=letrecloopsnextfi=matchnextswith|Done->true|Yield(a,_)whennot(fia)->false|Yield(_,s)->loopsnextf(i+1)|Skips->loopsnextfiinmatchtwith|Sequence(seed,next)->loopseednextf0letexistst~f=letrecloopsnextf=matchnextswith|Done->false|Yield(a,_)whenfa->true|Yield(_,s)|Skips->loopsnextfinmatchtwith|Sequence(seed,next)->loopseednextfletexistsit~f=letrecloopsnextfi=matchnextswith|Done->false|Yield(a,_)whenfia->true|Yield(_,s)->loopsnextf(i+1)|Skips->loopsnextfiinmatchtwith|Sequence(seed,next)->loopseednextf0letitert~f=letrecloopseednextf=matchnextseedwith|Done->()|Skips->loopsnextf|Yield(a,s)->beginfa;loopsnextfendinmatchtwith|Sequence(seed,next)->loopseednextfletis_emptyt=letrecloopsnext=matchnextswith|Done->true|Skips->loopsnext|Yield_->falseinmatchtwith|Sequence(seed,next)->loopseednextletmemta~equal=letrecloopsnexta=matchnextswith|Done->false|Yield(b,_)whenequalab->true|Yield(_,s)|Skips->loopsnextainmatchtwith|Sequence(seed,next)->loopseednextaletempty=Sequence((),fun()->Done)letbindt~f=unfold_step~f:(function|Sequence(seed,next),rest->matchnextseedwith|Done->beginmatchrestwith|Sequence(seed,next)->matchnextseedwith|Done->Done|Skips->Skip(empty,Sequence(s,next))|Yield(a,s)->Skip(fa,Sequence(s,next))end|Skips->Skip(Sequence(s,next),rest)|Yield(a,s)->Yield(a,(Sequence(s,next),rest)))~init:(empty,t)letreturnx=unfold_step~init:(Somex)~f:(function|None->Done|Somex->Yield(x,None))includeMonad.Make(structtypenonrec'at='atletmap=`Custommapletbind=bindletreturn=returnend)letnthsn=ifn<0thenNoneelseletrecloopisnext=matchnextswith|Done->None|Skips->loopisnext|Yield(a,s)->ifphys_equali0thenSomeaelseloop(i-1)snextinmatchswith|Sequence(s,next)->loopnsnextletnth_exnsn=ifn<0thenraise(Invalid_argument"Sequence.nth")elsematchnthsnwith|None->failwith"Sequence.nth"|Somex->xmoduleMerge_with_duplicates_element=structtype('a,'b)t=|Leftof'a|Rightof'b|Bothof'a*'b[@@deriving_inlinecompare,hash,sexp]letcompare:'a'b.('a->'a->int)->('b->'b->int)->('a,'b)t->('a,'b)t->int=fun_cmp__a->fun_cmp__b->funa__001_->funb__002_->ifPpx_compare_lib.phys_equala__001_b__002_then0else(match(a__001_,b__002_)with|(Left_a__003_,Left_b__004_)->_cmp__a_a__003__b__004_|(Left_,_)->(-1)|(_,Left_)->1|(Right_a__005_,Right_b__006_)->_cmp__b_a__005__b__006_|(Right_,_)->(-1)|(_,Right_)->1|(Both(_a__007_,_a__009_),Both(_b__008_,_b__010_))->(match_cmp__a_a__007__b__008_with|0->_cmp__b_a__009__b__010_|n->n))lethash_fold_t:typeab.(Ppx_hash_lib.Std.Hash.state->a->Ppx_hash_lib.Std.Hash.state)->(Ppx_hash_lib.Std.Hash.state->b->Ppx_hash_lib.Std.Hash.state)->Ppx_hash_lib.Std.Hash.state->(a,b)t->Ppx_hash_lib.Std.Hash.state=fun_hash_fold_a->fun_hash_fold_b->funhsv->funarg->matchargwith|Left_a0->lethsv=Ppx_hash_lib.Std.Hash.fold_inthsv0inlethsv=hsvin_hash_fold_ahsv_a0|Right_a0->lethsv=Ppx_hash_lib.Std.Hash.fold_inthsv1inlethsv=hsvin_hash_fold_bhsv_a0|Both(_a0,_a1)->lethsv=Ppx_hash_lib.Std.Hash.fold_inthsv2inlethsv=lethsv=hsvin_hash_fold_ahsv_a0in_hash_fold_bhsv_a1lett_of_sexp:typeab.(Ppx_sexp_conv_lib.Sexp.t->a)->(Ppx_sexp_conv_lib.Sexp.t->b)->Ppx_sexp_conv_lib.Sexp.t->(a,b)t=let_tp_loc="src/sequence.ml.Merge_with_duplicates_element.t"infun_of_a->fun_of_b->function|Ppx_sexp_conv_lib.Sexp.List((Ppx_sexp_conv_lib.Sexp.Atom("left"|"Left"as_tag))::sexp_args)as_sexp->(matchsexp_argswith|v0::[]->letv0=_of_av0inLeftv0|_->Ppx_sexp_conv_lib.Conv_error.stag_incorrect_n_args_tp_loc_tag_sexp)|Ppx_sexp_conv_lib.Sexp.List((Ppx_sexp_conv_lib.Sexp.Atom("right"|"Right"as_tag))::sexp_args)as_sexp->(matchsexp_argswith|v0::[]->letv0=_of_bv0inRightv0|_->Ppx_sexp_conv_lib.Conv_error.stag_incorrect_n_args_tp_loc_tag_sexp)|Ppx_sexp_conv_lib.Sexp.List((Ppx_sexp_conv_lib.Sexp.Atom("both"|"Both"as_tag))::sexp_args)as_sexp->(matchsexp_argswith|v0::v1::[]->letv0=_of_av0andv1=_of_bv1inBoth(v0,v1)|_->Ppx_sexp_conv_lib.Conv_error.stag_incorrect_n_args_tp_loc_tag_sexp)|Ppx_sexp_conv_lib.Sexp.Atom("left"|"Left")assexp->Ppx_sexp_conv_lib.Conv_error.stag_takes_args_tp_locsexp|Ppx_sexp_conv_lib.Sexp.Atom("right"|"Right")assexp->Ppx_sexp_conv_lib.Conv_error.stag_takes_args_tp_locsexp|Ppx_sexp_conv_lib.Sexp.Atom("both"|"Both")assexp->Ppx_sexp_conv_lib.Conv_error.stag_takes_args_tp_locsexp|Ppx_sexp_conv_lib.Sexp.List((Ppx_sexp_conv_lib.Sexp.List_)::_)assexp->Ppx_sexp_conv_lib.Conv_error.nested_list_invalid_sum_tp_locsexp|Ppx_sexp_conv_lib.Sexp.List[]assexp->Ppx_sexp_conv_lib.Conv_error.empty_list_invalid_sum_tp_locsexp|sexp->Ppx_sexp_conv_lib.Conv_error.unexpected_stag_tp_locsexpletsexp_of_t:typeab.(a->Ppx_sexp_conv_lib.Sexp.t)->(b->Ppx_sexp_conv_lib.Sexp.t)->(a,b)t->Ppx_sexp_conv_lib.Sexp.t=fun_of_a->fun_of_b->function|Leftv0->letv0=_of_av0inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Left";v0]|Rightv0->letv0=_of_bv0inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Right";v0]|Both(v0,v1)->letv0=_of_av0andv1=_of_bv1inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Both";v0;v1][@@@end]endletmerge_with_duplicates(Sequence(s1,next1))(Sequence(s2,next2))~compare=letunshadowed_compare=compareinletopenMerge_with_duplicates_elementinletnext=function|Skips1,s2->Skip(next1s1,s2)|s1,Skips2->Skip(s1,next2s2)|(Yield(a,s1')ass1),(Yield(b,s2')ass2)->letcomparison=unshadowed_compareabinifcomparison<0thenYield(Lefta,(Skips1',s2))elseifcomparison=0thenYield(Both(a,b),(Skips1',Skips2'))elseYield(Rightb,(s1,Skips2'))|Done,Done->Done|Yield(a,s1),Done->Yield(Lefta,(Skips1,Done))|Done,Yield(b,s2)->Yield(Rightb,(Done,Skips2))inSequence((Skips1,Skips2),next)letmerges1s2~compare=map(merge_with_duplicatess1s2~compare)~f:(functionLeftx|Rightx|Both(x,_)->x)lethds=letrecloopsnext=matchnextswith|Done->None|Skips->loopsnext|Yield(a,_)->Someainmatchswith|Sequence(s,next)->loopsnextlethd_exns=matchhdswith|None->failwith"hd_exn"|Somea->alettls=letrecloopsnext=matchnextswith|Done->None|Skips->loopsnext|Yield(_,a)->Someainmatchswith|Sequence(s,next)->matchloopsnextwith|None->None|Somes->Some(Sequence(s,next))lettl_eagerly_exns=matchtlswith|None->failwith"Sequence.tl_exn"|Somes->sletlift_identitynexts=matchnextswith|Done->Done|Skips->Skip(`Identitys)|Yield(a,s)->Yield(a,`Identitys)letnexts=letrecloopsnext=matchnextswith|Done->None|Skips->loopsnext|Yield(a,s)->Some(a,Sequence(s,next))inmatchswith|Sequence(s,next)->loopsnextletfilter_opts=matchswith|Sequence(s,next)->Sequence(s,funs->matchnextswith|Done->Done|Skips->Skips|Yield(None,s)->Skips|Yield(Somea,s)->Yield(a,s))letfilter_maps~f=filter_opt(maps~f)letfilter_mapis~f=filter_map(mapis~f:(funis->(i,s)))~f:(fun(i,s)->fis)letsplit_nsn=letrecloopsiaccumnext=ifi<=0then(List.revaccum,Sequence(s,next))elsematchnextswith|Done->(List.revaccum,empty)|Skips->loopsiaccumnext|Yield(a,s)->loops(i-1)(a::accum)nextinmatchswith|Sequence(s,next)->loopsn[]nextletchunks_exntn=ifn<=0thenraise(Invalid_argument"Sequence.chunks_exn")elseunfold_step~init:t~f:(funt->matchsplit_ntnwith|[],_empty->Done|_::_asxs,t->Yield(xs,t))letfindis~f=find(mapis~f:(funis->(i,s)))~f:(fun(i,s)->fis)letfind_exns~f=matchfinds~fwith|None->failwith"Sequence.find_exn"|Somex->xletappends1s2=matchs1,s2with|Sequence(s1,next1),Sequence(s2,next2)->Sequence(`First_lists1,function|`First_lists1->beginmatchnext1s1with|Done->Skip(`Second_lists2)|Skips1->Skip(`First_lists1)|Yield(a,s1)->Yield(a,`First_lists1)end|`Second_lists2->beginmatchnext2s2with|Done->Done|Skips2->Skip(`Second_lists2)|Yield(a,s2)->Yield(a,`Second_lists2)end)letconcat_maps~f=binds~fletconcats=concat_maps~f:Fn.idletconcat_mapis~f=concat_map(mapis~f:(funis->(i,s)))~f:(fun(i,s)->fis)letzip(Sequence(s1,next1))(Sequence(s2,next2))=letnext=function|Yield(a,s1),Yield(b,s2)->Yield((a,b),(Skips1,Skips2))|Done,_|_,Done->Done|Skips1,s2->Skip(next1s1,s2)|s1,Skips2->Skip(s1,next2s2)inSequence((Skips1,Skips2),next)letzip_full(Sequence(s1,next1))(Sequence(s2,next2))=letnext=function|Yield(a,s1),Yield(b,s2)->Yield(`Both(a,b),(Skips1,Skips2))|Done,Done->Done|Skips1,s2->Skip(next1s1,s2)|s1,Skips2->Skip(s1,next2s2)|Done,Yield(b,s2)->Yield((`Rightb),(Done,next2s2))|Yield(a,s1),Done->Yield((`Lefta),(next1s1,Done))inSequence((Skips1,Skips2),next)letbounded_length(Sequence(seed,next))~at_most=letrecloopiseednext=ifi>at_mostthen`Greaterelsematchnextseedwith|Done->`Isi|Skipseed->loopiseednext|Yield(_,seed)->loop(i+1)seednextinloop0seednextletlength_is_bounded_by?(min=(-1))?maxt=letlength_is_at_least(Sequence(s,next))=letrecloopsacc=ifacc>=minthentrueelsematchnextswith|Done->false|Skips->loopsacc|Yield(_,s)->loops(acc+1)inloops0inmatchmaxwith|None->length_is_at_leastt|Somemax->beginmatchbounded_lengtht~at_most:maxwith|`Islenwhenlen>=min->true|_->falseendletiteris~f=iter(mapis~f:(funis->(i,s)))~f:(fun(i,s)->fis)letfoldis~init~f=fold~init(mapis~f:(funis->(i,s)))~f:(funacc(i,s)->fiaccs)letreduces~f=matchnextswith|None->None|Some(a,s)->Some(folds~init:a~f)letreduce_exns~f=matchreduces~fwith|None->failwith"Sequence.reduce_exn"|Someres->resletgroup(Sequence(s,next))~break=unfold_step~init:(Some([],s))~f:(function|None->Done|Some(acc,s)->matchacc,nextswith|_,Skips->Skip(Some(acc,s))|[],Done->Done|acc,Done->Yield(List.revacc,None)|[],Yield(cur,s)->Skip(Some([cur],s))|prev::_asacc,Yield(cur,s)->ifbreakprevcurthenYield(List.revacc,Some([cur],s))elseSkip(Some(cur::acc,s)));;letfind_consecutive_duplicate(Sequence(s,next))~equal=letreclooplast_elts=matchnextswith|Done->None|Skips->looplast_elts|Yield(a,s)->matchlast_eltwith|Somebwhenequalab->Some(b,a)|None|Some_->loop(Somea)sinloopNonesletremove_consecutive_duplicatess~equal=unfold_withs~init:None~f:(funpreva->matchprevwith|Somebwhenequalab->Skip(Somea)|None|Some_->Yield(a,Somea))letcounts~f=length(filters~f)letcountit~f=length(filterit~f)letsummt~f=Container.sum~foldmt~fletmin_eltt~compare=Container.min_elt~foldt~compareletmax_eltt~compare=Container.max_elt~foldt~compareletinitn~f=unfold_step~init:0~f:(funi->ifi>=nthenDoneelseYield(fi,i+1))letsubs~pos~len=ifpos<0||len<0thenfailwith"Sequence.sub";matchswith|Sequence(s,next)->Sequence((0,s),(fun(i,s)->ifi-pos>=lenthenDoneelsematchnextswith|Done->Done|Skips->Skip(i,s)|Yield(a,s)wheni>=pos->Yield(a,(i+1,s))|Yield(_,s)->Skip(i+1,s)))lettakeslen=iflen<0thenfailwith"Sequence.take";matchswith|Sequence(s,next)->Sequence((0,s),(fun(i,s)->ifi>=lenthenDoneelsematchnextswith|Done->Done|Skips->Skip(i,s)|Yield(a,s)->Yield(a,(i+1,s))))letdropslen=iflen<0thenfailwith"Sequence.drop";matchswith|Sequence(s,next)->Sequence((0,s),(fun(i,s)->matchnextswith|Done->Done|Skips->Skip(i,s)|Yield(a,s)wheni>=len->Yield(a,(i+1,s))|Yield(_,s)->Skip(i+1,s)))lettake_whiles~f=matchswith|Sequence(s,next)->Sequence(s,funs->matchnextswith|Done->Done|Skips->Skips|Yield(a,s)whenfa->Yield(a,s)|Yield(_,_)->Done)letdrop_whiles~f=matchswith|Sequence(s,next)->Sequence(`Droppings,function|`Droppings->beginmatchnextswith|Done->Done|Skips->Skip(`Droppings)|Yield(a,s)whenfa->Skip(`Droppings)|Yield(a,s)->Yield(a,`Identitys)end|`Identitys->lift_identitynexts)letshift_rightsx=matchswith|Sequence(seed,next)->Sequence(`Consing(seed,x),function|`Consing(seed,x)->Yield(x,`Identityseed)|`Identitys->lift_identitynexts)letshift_right_with_listsl=append(of_listl)sletshift_left=dropmoduleInfix=structlet(@)=appendendletintersperses~sep=matchswith|Sequence(s,next)->Sequence(`Inits,function|`Inits->beginmatchnextswith|Done->Done|Skips->Skip(`Inits)|Yield(a,s)->Yield(a,`Runnings)end|`Runnings->beginmatchnextswith|Done->Done|Skips->Skip(`Runnings)|Yield(a,s)->Yield(sep,`Putting(a,s))end|`Putting(a,s)->Yield(a,`Runnings))letrepeatx=unfold_step~init:x~f:(funx->Yield(x,x))letcycle_list_exnxs=ifList.is_emptyxsthenraise(Invalid_argument"Sequence.cycle_list_exn");lets=of_listxsinconcat_map~f:(fun()->s)(repeat())letcartesian_productsasb=concat_mapsa~f:(funa->zip(repeata)sb)letsingletonx=returnxletdelayed_folds~init~f~finish=Expert.delayed_fold_steps~init~finish~f:(funaccoption~k->matchoptionwith|None->kacc|Somea->facca~k)letfold_m~bind~returnt~init~f=Expert.delayed_fold_stept~init~f:(funaccoption~k->matchoptionwith|None->bind(returnacc)~f:k|Somea->bind(facca)~f:k)~finish:return;;letiter_m~bind~returnt~f=Expert.delayed_fold_stept~init:()~f:(fun()option~k->matchoptionwith|None->bind(return())~f:k|Somea->bind(fa)~f:k)~finish:return;;letfold_untils~init~f~finish=letrecloopsnextf=funacc->matchnextswith|Done->finishacc|Skips->loopsnextfacc|Yield(a,s)->match(facca:('a,'b)Continue_or_stop.t)with|Stopx->x|Continueacc->loopsnextfaccinmatchswith|Sequence(s,next)->loopsnextfinitletfold_results~init~f=letrecloopsnextf=funacc->matchnextswith|Done->Result.returnacc|Skips->loopsnextfacc|Yield(a,s)->match(facca:(_,_)Result.t)with|Error_ase->e|Okacc->loopsnextfaccinmatchswith|Sequence(s,next)->loopsnextfinitletforce_eagerlyt=of_list(to_listt)letmemoize(typea)(Sequence(s,next))=letmoduleM=structtypet=Tof(a,t)Step.tLazy.tendinletrecmemoizes=M.T(lazy(find_steps))andfind_steps=matchnextswith|Done->Done|Skips->find_steps|Yield(a,s)->Yield(a,memoizes)inSequence(memoizes,(fun(M.Tl)->Lazy.forcel))letdrop_eagerlyslen=letrecloopi~lensnext=ifi>=lenthenSequence(s,next)elsematchnextswith|Done->empty|Skips->loopi~lensnext|Yield(_,s)->loop(i+1)~lensnextinmatchswith|Sequence(s,next)->loop0~lensnextletdrop_while_option(Sequence(s,next))~f=letrecloops=matchnextswith|Done->None|Skips->loops|Yield(x,s)->iffxthenloopselseSome(x,Sequence(s,next))inloopsletcomparecompare_at1t2=With_return.with_return(funr->iter(zip_fullt1t2)~f:(function|`Left_->r.return1|`Right_->r.return(-1)|`Both(v1,v2)->letc=compare_av1v2inifc<>0thenr.returnc);0);;;letround_robinlist=letnext(todo_stack,done_stack)=matchtodo_stackwith|Sequence(s,f)::todo_stack->beginmatchfswith|Yield(x,s)->Yield(x,(todo_stack,Sequence(s,f)::done_stack))|Skips->Skip(Sequence(s,f)::todo_stack,done_stack)|Done->Skip(todo_stack,done_stack)end|[]->ifList.is_emptydone_stackthenDoneelseSkip(List.revdone_stack,[])inletstate=list,[]inSequence(state,next)letinterleave(Sequence(s1,f1))=letnext(todo_stack,done_stack,s1)=matchtodo_stackwith|Sequence(s2,f2)::todo_stack->beginmatchf2s2with|Yield(x,s2)->Yield(x,(todo_stack,Sequence(s2,f2)::done_stack,s1))|Skips2->Skip(todo_stack,Sequence(s2,f2)::done_stack,s1)|Done->Skip(todo_stack,done_stack,s1)end|[]->beginmatchf1s1,done_stackwith|Yield(t,s1),_->Skip(List.rev(t::done_stack),[],s1)|Skips1,_->Skip(List.revdone_stack,[],s1)|Done,_::_->Skip(List.revdone_stack,[],s1)|Done,[]->Doneendinletstate=[],[],s1inSequence(state,next)letinterleaved_cartesian_products1s2=maps1~f:(funx1->maps2~f:(funx2->(x1,x2)))|>interleavemoduleGenerator=structtype'eltsteps=Wrapof('elt,unit->'eltsteps)Step.tletunwrap(Wrapstep)=stepmoduleT=structtype('a,'elt)t=('a->'eltsteps)->'eltstepsletreturnx=();funk->kxletbindm~f=();funk->m(funa->letm'=fainm'k)letmapm~f=();funk->m(funa->k(fa))letmap=`CustommapendincludeTincludeMonad.Make2(T)letyielde=();funk->Wrap(Yield(e,k))letto_stepst=t(fun()->WrapDone)letof_sequencesequence=delayed_foldsequence~init:()~f:(fun()x~kf->Wrap(Yield(x,fun()->k()f)))~finish:returnletrunt=letinit()=to_stepstinletfthunk=unwrap(thunk())inunfold_step~init~fend