1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138open!ImportopenContainer_intf.ExportmoduleArray=Array0moduleList=List1moduleStep=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)->(matchnextinner_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))))|`Inner_finishedstate->(matchfinishing_stepstatewith|Done->Done|Skipstate->Skip(`Inner_finishedstate)|Yield(y,state)->Yield(y,`Inner_finishedstate)));;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)->loopseedinitnextf;;letto_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))else(matchnextswith|Done->[]|Skips->to_listsnexti|Yield(a,s)->a::to_listsnext(i-1))into_listsnext500;;letsexp_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:step;;letof_lazyt_lazy=unfold_step~init:t_lazy~f:(funt_lazy->let(Sequence(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)->loop0seednext;;letto_list_rev_with_lengtht=foldt~init:([],0)~f:(fun(l,i)x->x::l,i+1)letto_arrayt=letl,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;a;;letfindt~f=letrecloopsnextf=matchnextswith|Done->None|Yield(a,_)whenfa->Somea|Yield(_,s)|Skips->loopsnextfinmatchtwith|Sequence(seed,next)->loopseednextf;;letfind_mapt~f=letrecloopsnextf=matchnextswith|Done->None|Yield(a,s)->(matchfawith|None->loopsnextf|some_b->some_b)|Skips->loopsnextfinmatchtwith|Sequence(seed,next)->loopseednextf;;letfind_mapit~f=letrecloopsnextfi=matchnextswith|Done->None|Yield(a,s)->(matchfiawith|None->loopsnextf(i+1)|some_b->some_b)|Skips->loopsnextfiinmatchtwith|Sequence(seed,next)->loopseednextf0;;letfor_allt~f=letrecloopsnextf=matchnextswith|Done->true|Yield(a,_)whennot(fa)->false|Yield(_,s)|Skips->loopsnextfinmatchtwith|Sequence(seed,next)->loopseednextf;;letfor_allit~f=letrecloopsnextfi=matchnextswith|Done->true|Yield(a,_)whennot(fia)->false|Yield(_,s)->loopsnextf(i+1)|Skips->loopsnextfiinmatchtwith|Sequence(seed,next)->loopseednextf0;;letexistst~f=letrecloopsnextf=matchnextswith|Done->false|Yield(a,_)whenfa->true|Yield(_,s)|Skips->loopsnextfinmatchtwith|Sequence(seed,next)->loopseednextf;;letexistsit~f=letrecloopsnextfi=matchnextswith|Done->false|Yield(a,_)whenfia->true|Yield(_,s)->loopsnextf(i+1)|Skips->loopsnextfiinmatchtwith|Sequence(seed,next)->loopseednextf0;;letitert~f=letrecloopseednextf=matchnextseedwith|Done->()|Skips->loopsnextf|Yield(a,s)->fa;loopsnextfinmatchtwith|Sequence(seed,next)->loopseednextf;;letis_emptyt=letrecloopsnext=matchnextswith|Done->true|Skips->loopsnext|Yield_->falseinmatchtwith|Sequence(seed,next)->loopseednext;;letmemta~equal=letrecloopsnexta=matchnextswith|Done->false|Yield(b,_)whenequalab->true|Yield(_,s)|Skips->loopsnextainmatchtwith|Sequence(seed,next)->loopseednexta;;letempty=Sequence((),fun()->Done)letbindt~f=unfold_step~f:(function|Sequence(seed,next),rest->(matchnextseedwith|Done->(matchrestwith|Sequence(seed,next)->(matchnextseedwith|Done->Done|Skips->Skip(empty,Sequence(s,next))|Yield(a,s)->Skip(fa,Sequence(s,next))))|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<0thenNoneelse(letrecloopisnext=matchnextswith|Done->None|Skips->loopisnext|Yield(a,s)->ifphys_equali0thenSomeaelseloop(i-1)snextinmatchswith|Sequence(s,next)->loopnsnext);;letnth_exnsn=ifn<0thenraise(Invalid_argument"Sequence.nth")else(matchnthsnwith|None->failwith"Sequence.nth"|Somex->x);;moduleMerge_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:(function|Leftx|Rightx|Both(x,_)->x);;lethds=letrecloopsnext=matchnextswith|Done->None|Skips->loopsnext|Yield(a,_)->Someainmatchswith|Sequence(s,next)->loopsnext;;lethd_exns=matchhdswith|None->failwith"hd_exn"|Somea->a;;lettls=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->s;;letlift_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)->loopsnext;;letfilter_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<=0thenList.revaccum,Sequence(s,next)else(matchnextswith|Done->List.revaccum,empty|Skips->loopsiaccumnext|Yield(a,s)->loops(i-1)(a::accum)next)inmatchswith|Sequence(s,next)->loopsn[]next;;letchunks_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->x;;letappends1s2=matchs1,s2with|Sequence(s1,next1),Sequence(s2,next2)->Sequence(`First_lists1,function|`First_lists1->(matchnext1s1with|Done->Skip(`Second_lists2)|Skips1->Skip(`First_lists1)|Yield(a,s1)->Yield(a,`First_lists1))|`Second_lists2->(matchnext2s2with|Done->Done|Skips2->Skip(`Second_lists2)|Yield(a,s2)->Yield(a,`Second_lists2)));;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`Greaterelse(matchnextseedwith|Done->`Isi|Skipseed->loopiseednext|Yield(_,seed)->loop(i+1)seednext)inloop0seednext;;letlength_is_bounded_by?(min=-1)?maxt=letlength_is_at_least(Sequence(s,next))=letrecloopsacc=ifacc>=minthentrueelse(matchnextswith|Done->false|Skips->loopsacc|Yield(_,s)->loops(acc+1))inloops0inmatchmaxwith|None->length_is_at_leastt|Somemax->(matchbounded_lengtht~at_most:maxwith|`Islenwhenlen>=min->true|_->false);;letiteris~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->res;;letgroup(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)s)inloopNones;;letremove_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>=lenthenDoneelse(matchnextswith|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>=lenthenDoneelse(matchnextswith|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->(matchnextswith|Done->Done|Skips->Skip(`Droppings)|Yield(a,s)whenfa->Skip(`Droppings)|Yield(a,s)->Yield(a,`Identitys))|`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->(matchnextswith|Done->Done|Skips->Skip(`Inits)|Yield(a,s)->Yield(a,`Runnings))|`Runnings->(matchnextswith|Done->Done|Skips->Skip(`Runnings)|Yield(a,s)->Yield(sep,`Putting(a,s)))|`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=letrecloopsnextfacc=matchnextswith|Done->finishacc|Skips->loopsnextfacc|Yield(a,s)->(match(facca:('a,'b)Continue_or_stop.t)with|Stopx->x|Continueacc->loopsnextfacc)inmatchswith|Sequence(s,next)->loopsnextfinit;;letfold_results~init~f=letrecloopsnextfacc=matchnextswith|Done->Result.returnacc|Skips->loopsnextfacc|Yield(a,s)->(match(facca:(_,_)Result.t)with|Error_ase->e|Okacc->loopsnextfacc)inmatchswith|Sequence(s,next)->loopsnextfinit;;letforce_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)else(matchnextswith|Done->empty|Skips->loopi~lensnext|Yield(_,s)->loop(i+1)~lensnext)inmatchswith|Sequence(s,next)->loop0~lensnext;;letdrop_while_option(Sequence(s,next))~f=letrecloops=matchnextswith|Done->None|Skips->loops|Yield(x,s)->iffxthenloopselseSome(x,Sequence(s,next))inloops;;letcomparecompare_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);;letequalequal_at1t2=for_all(zip_fullt1t2)~f:(function|`Both(a1,a2)->equal_aa1a2|`Left_|`Right_->false);;letround_robinlist=letnext(todo_stack,done_stack)=matchtodo_stackwith|Sequence(s,f)::todo_stack->(matchfswith|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))|[]->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->(matchf2s2with|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))|[]->(matchf1s1,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,[]->Done)inletstate=[],[],s1inSequence(state,next);;letinterleaved_cartesian_products1s2=maps1~f:(funx1->maps2~f:(funx2->x1,x2))|>interleave;;moduleGenerator=structtype'eltsteps=Wrapof('elt,unit->'eltsteps)Step.tletunwrap(Wrapstep)=stepmoduleT=structtype('a,'elt)t=('a->'eltsteps)->'eltstepsletreturnxk=kxletbindm~fk=m(funa->letm'=fainm'k);;letmapm~fk=m(funa->k(fa))letmap=`CustommapendincludeTincludeMonad.Make2(T)letyieldek=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:return;;letrunt=letinit()=to_stepstinletfthunk=unwrap(thunk())inunfold_step~init~f;;end