123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167open!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_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<0theninvalid_arg"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_cmp__ba__001_b__002_->ifPpx_compare_lib.phys_equala__001_b__002_then0else(matcha__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_hash_fold_bhsvarg->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_a1;;lett_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="sequence.ml.Merge_with_duplicates_element.t"infun_of_a_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_locsexp;;letsexp_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_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<=0theninvalid_arg"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_emptyxstheninvalid_arg"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;;letof_seq(seq:_Caml.Seq.t)=unfold_step~init:seq~f:(funseq->matchseq()with|Nil->Done|Cons(hd,tl)->Yield(hd,tl));;letto_seq(Sequence(state,next))=letrecloopstate=matchnextstatewith|Done->Caml.Seq.Nil|Skipstate->loopstate|Yield(hd,state)->Caml.Seq.Cons(hd,fun()->loopstate)infun()->loopstate;;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