1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246open!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:'a's.('a->Sexplib0.Sexp.t)->('s->Sexplib0.Sexp.t)->('a,'s)t->Sexplib0.Sexp.t=fun(typea__009_s__010_):((a__009_->Sexplib0.Sexp.t)->(s__010_->Sexplib0.Sexp.t)->(a__009_,s__010_)t->Sexplib0.Sexp.t)->fun_of_a__001__of_s__002_->function|Done->Sexplib0.Sexp.Atom"Done"|Skiparg0__003_->letres0__004_=_of_s__002_arg0__003_inSexplib0.Sexp.List[Sexplib0.Sexp.Atom"Skip";res0__004_]|Yield(arg0__005_,arg1__006_)->letres0__007_=_of_a__001_arg0__005_andres1__008_=_of_s__002_arg1__006_inSexplib0.Sexp.List[Sexplib0.Sexp.Atom"Yield";res0__007_;res1__008_];;[@@@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,sexp_grammar]letcompare:'a'b.('a->'a->int)->('b->'b->int)->('a,'b)t->('a,'b)t->int=fun_cmp__a_cmp__ba__011_b__012_->ifPpx_compare_lib.phys_equala__011_b__012_then0else(matcha__011_,b__012_with|Left_a__013_,Left_b__014_->_cmp__a_a__013__b__014_|Left_,_->-1|_,Left_->1|Right_a__015_,Right_b__016_->_cmp__b_a__015__b__016_|Right_,_->-1|_,Right_->1|Both(_a__017_,_a__019_),Both(_b__018_,_b__020_)->(match_cmp__a_a__017__b__018_with|0->_cmp__b_a__019__b__020_|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:'a'b.(Sexplib0.Sexp.t->'a)->(Sexplib0.Sexp.t->'b)->Sexplib0.Sexp.t->('a,'b)t=fun(typea__044_b__045_):((Sexplib0.Sexp.t->a__044_)->(Sexplib0.Sexp.t->b__045_)->Sexplib0.Sexp.t->(a__044_,b__045_)t)->leterror_source__025_="sequence.ml.Merge_with_duplicates_element.t"infun_of_a__021__of_b__022_->function|Sexplib0.Sexp.List(Sexplib0.Sexp.Atom(("left"|"Left")as_tag__028_)::sexp_args__029_)as_sexp__027_->(matchsexp_args__029_with|[arg0__030_]->letres0__031_=_of_a__021_arg0__030_inLeftres0__031_|_->Sexplib0.Sexp_conv_error.stag_incorrect_n_argserror_source__025__tag__028__sexp__027_)|Sexplib0.Sexp.List(Sexplib0.Sexp.Atom(("right"|"Right")as_tag__033_)::sexp_args__034_)as_sexp__032_->(matchsexp_args__034_with|[arg0__035_]->letres0__036_=_of_b__022_arg0__035_inRightres0__036_|_->Sexplib0.Sexp_conv_error.stag_incorrect_n_argserror_source__025__tag__033__sexp__032_)|Sexplib0.Sexp.List(Sexplib0.Sexp.Atom(("both"|"Both")as_tag__038_)::sexp_args__039_)as_sexp__037_->(matchsexp_args__039_with|[arg0__040_;arg1__041_]->letres0__042_=_of_a__021_arg0__040_andres1__043_=_of_b__022_arg1__041_inBoth(res0__042_,res1__043_)|_->Sexplib0.Sexp_conv_error.stag_incorrect_n_argserror_source__025__tag__038__sexp__037_)|Sexplib0.Sexp.Atom("left"|"Left")assexp__026_->Sexplib0.Sexp_conv_error.stag_takes_argserror_source__025_sexp__026_|Sexplib0.Sexp.Atom("right"|"Right")assexp__026_->Sexplib0.Sexp_conv_error.stag_takes_argserror_source__025_sexp__026_|Sexplib0.Sexp.Atom("both"|"Both")assexp__026_->Sexplib0.Sexp_conv_error.stag_takes_argserror_source__025_sexp__026_|Sexplib0.Sexp.List(Sexplib0.Sexp.List_::_)assexp__024_->Sexplib0.Sexp_conv_error.nested_list_invalid_sumerror_source__025_sexp__024_|Sexplib0.Sexp.List[]assexp__024_->Sexplib0.Sexp_conv_error.empty_list_invalid_sumerror_source__025_sexp__024_|sexp__024_->Sexplib0.Sexp_conv_error.unexpected_stagerror_source__025_sexp__024_;;letsexp_of_t:'a'b.('a->Sexplib0.Sexp.t)->('b->Sexplib0.Sexp.t)->('a,'b)t->Sexplib0.Sexp.t=fun(typea__056_b__057_):((a__056_->Sexplib0.Sexp.t)->(b__057_->Sexplib0.Sexp.t)->(a__056_,b__057_)t->Sexplib0.Sexp.t)->fun_of_a__046__of_b__047_->function|Leftarg0__048_->letres0__049_=_of_a__046_arg0__048_inSexplib0.Sexp.List[Sexplib0.Sexp.Atom"Left";res0__049_]|Rightarg0__050_->letres0__051_=_of_b__047_arg0__050_inSexplib0.Sexp.List[Sexplib0.Sexp.Atom"Right";res0__051_]|Both(arg0__052_,arg1__053_)->letres0__054_=_of_a__046_arg0__052_andres1__055_=_of_b__047_arg1__053_inSexplib0.Sexp.List[Sexplib0.Sexp.Atom"Both";res0__054_;res1__055_];;let(t_sexp_grammar:'aSexplib0.Sexp_grammar.t->'bSexplib0.Sexp_grammar.t->('a,'b)tSexplib0.Sexp_grammar.t)=fun_'a_sexp_grammar_'b_sexp_grammar->{untyped=Variant{case_sensitivity=Case_sensitive_except_first_character;clauses=[No_tag{name="Left";clause_kind=List_clause{args=Cons(_'a_sexp_grammar.untyped,Empty)}};No_tag{name="Right";clause_kind=List_clause{args=Cons(_'b_sexp_grammar.untyped,Empty)}};No_tag{name="Both";clause_kind=List_clause{args=Cons(_'a_sexp_grammar.untyped,Cons(_'b_sexp_grammar.untyped,Empty))}}]}};;[@@@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);;letmerge_deduped_and_sorteds1s2~compare=map(merge_with_duplicatess1s2~compare)~f:(function|Leftx|Rightx|Both(x,_)->x);;let(merge[@deprecated"[since 2021-07] For identical behavior, use \
[Sequence.merge_deduped_and_sorted], but consider using \
[Sequence.merge_sorted] instead."])=merge_deduped_and_sorted;;letmerge_sorted(Sequence(s1,next1))(Sequence(s2,next2))~compare=letnext=function|Skips1,s2->Skip(next1s1,s2)|s1,Skips2->Skip(s1,next2s2)|(Yield(a,s1')ass1),(Yield(b,s2')ass2)->letcomparison=compareabinifcomparison<=0thenYield(a,(Skips1',s2))elseYield(b,(s1,Skips2'))|Done,Done->Done|Yield(a,s1),Done->Yield(a,(Skips1,Done))|Done,Yield(b,s2)->Yield(b,(Done,Skips2))inSequence((Skips1,Skips2),next);;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