123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280open!ImportincludeEither_intfmoduleArray=Array0type('f,'s)t=|Firstof'f|Secondof's[@@deriving_inlinecompare,hash,sexp]letcompare:'f's.('f->'f->int)->('s->'s->int)->('f,'s)t->('f,'s)t->int=fun_cmp__f->fun_cmp__s->funa__001_->funb__002_->ifPpx_compare_lib.phys_equala__001_b__002_then0else(match(a__001_,b__002_)with|(First_a__003_,First_b__004_)->_cmp__f_a__003__b__004_|(First_,_)->(-1)|(_,First_)->1|(Second_a__005_,Second_b__006_)->_cmp__s_a__005__b__006_)lethash_fold_t:typefs.(Ppx_hash_lib.Std.Hash.state->f->Ppx_hash_lib.Std.Hash.state)->(Ppx_hash_lib.Std.Hash.state->s->Ppx_hash_lib.Std.Hash.state)->Ppx_hash_lib.Std.Hash.state->(f,s)t->Ppx_hash_lib.Std.Hash.state=fun_hash_fold_f->fun_hash_fold_s->funhsv->funarg->matchargwith|First_a0->lethsv=Ppx_hash_lib.Std.Hash.fold_inthsv0inlethsv=hsvin_hash_fold_fhsv_a0|Second_a0->lethsv=Ppx_hash_lib.Std.Hash.fold_inthsv1inlethsv=hsvin_hash_fold_shsv_a0lett_of_sexp:typefs.(Ppx_sexp_conv_lib.Sexp.t->f)->(Ppx_sexp_conv_lib.Sexp.t->s)->Ppx_sexp_conv_lib.Sexp.t->(f,s)t=let_tp_loc="src/either.ml.t"infun_of_f->fun_of_s->function|Ppx_sexp_conv_lib.Sexp.List((Ppx_sexp_conv_lib.Sexp.Atom("first"|"First"as_tag))::sexp_args)as_sexp->(matchsexp_argswith|v0::[]->letv0=_of_fv0inFirstv0|_->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("second"|"Second"as_tag))::sexp_args)as_sexp->(matchsexp_argswith|v0::[]->letv0=_of_sv0inSecondv0|_->Ppx_sexp_conv_lib.Conv_error.stag_incorrect_n_args_tp_loc_tag_sexp)|Ppx_sexp_conv_lib.Sexp.Atom("first"|"First")assexp->Ppx_sexp_conv_lib.Conv_error.stag_takes_args_tp_locsexp|Ppx_sexp_conv_lib.Sexp.Atom("second"|"Second")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:typefs.(f->Ppx_sexp_conv_lib.Sexp.t)->(s->Ppx_sexp_conv_lib.Sexp.t)->(f,s)t->Ppx_sexp_conv_lib.Sexp.t=fun_of_f->fun_of_s->function|Firstv0->letv0=_of_fv0inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"First";v0]|Secondv0->letv0=_of_sv0inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Second";v0][@@@end]letswap=function|Firstx->Secondx|Secondx->Firstx;;letis_first=function|First_->true|Second_->false;;letis_second=function|First_->false|Second_->true;;letvalue(Firstx|Secondx)=xletvalue_mapt~first~second=matchtwith|Firstx->firstx|Secondx->secondx;;letiter=value_mapletmapt~first~second=matchtwith|Firstx->First(firstx)|Secondx->Second(secondx);;letfirstx=Firstxletsecondx=Secondxletequaleq1eq2t1t2=matcht1,t2with|Firstx,Firsty->eq1xy|Secondx,Secondy->eq2xy|First_,Second_|Second_,First_->false;;letinvariantfs=function|Firstx->fx|Secondy->sy;;moduleMake_focused(M:sigtype(+'a,+'b)tvalreturn:'a->('a,_)tvalother:'b->(_,'b)tvaleither:('a,'b)t->return:('a->'c)->other:('b->'c)->'cvalcombine:('a,'d)t->('b,'d)t->f:('a->'b->'c)->other:('d->'d->'d)->('c,'d)tvalbind:('a,'b)t->f:('a->('c,'b)t)->('c,'b)tend)=structincludeMopenWith_returnletmapt~f=bindt~f:(funx->return(fx))includeMonad.Make2(structtypenonrec('a,'b)t=('a,'b)tletreturn=returnletbind=bindletmap=`Custommapend)moduleApp=Applicative.Make2(structtypenonrec('a,'b)t=('a,'b)tletreturn=returnletapplyt1t2=bindt1~f:(funf->bindt2~f:(funx->return(fx)))letmap=`Custommapend)includeAppletcombine_all=letrecother_loopfacc=function|[]->otheracc|t::ts->eithert~return:(fun_->other_loopfaccts)~other:(funo->other_loopf(facco)ts)inletrecreturn_loopfacc=function|[]->return(List.revacc)|t::ts->eithert~return:(funx->return_loopf(x::acc)ts)~other:(funo->other_loopfots)infunts~f->return_loopf[]ts;;letcombine_all_unit=letrecother_loopfacc=function|[]->otheracc|t::ts->eithert~return:(fun()->other_loopfaccts)~other:(funo->other_loopf(facco)ts)inletrecreturn_loopf=function|[]->return()|t::ts->eithert~return:(fun()->return_loopfts)~other:(funo->other_loopfots)infunts~f->return_loopfts;;letto_optiont=eithert~return:Option.some~other:(fun_->None)letvaluet~default=eithert~return:Fn.id~other:(fun_->default)letwith_returnf=with_return(funret->other(f(With_return.prependret~f:return)));;endmoduleFirst=Make_focused(structtypenonrec('a,'b)t=('a,'b)tletreturn=firstletother=secondleteithert~return~other=matchtwith|Firstx->returnx|Secondy->othery;;letcombinet1t2~f~other=matcht1,t2with|Firstx,Firsty->First(fxy)|Secondx,Secondy->Second(otherxy)|Secondx,_|_,Secondx->Secondx;;letbindt~f=matchtwith|Firstx->fx(* Reuse the value in order to avoid allocation. *)|Second_asy->y;;end)moduleSecond=Make_focused(structtypenonrec('a,'b)t=('b,'a)tletreturn=secondletother=firstleteithert~return~other=matchtwith|Secondy->returny|Firstx->otherx;;letcombinet1t2~f~other=matcht1,t2with|Secondx,Secondy->Second(fxy)|Firstx,Firsty->First(otherxy)|Firstx,_|_,Firstx->Firstx;;letbindt~f=matchtwith|Secondx->fx(* Reuse the value in order to avoid allocation, like [First.bind] above. *)|First_asy->y;;end)moduleExport=structtype('f,'s)_either=('f,'s)t=|Firstof'f|Secondof'send