123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210(* This file is part of Lwt, released under the MIT license. See LICENSE.md for
details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)(* A survey and measurements of more optimized implementations can be found at:
https://jsthomas.github.io/map-comparison.html
See discussion in https://github.com/ocsigen/lwt/pull/347. *)lettail_recursive_mapfl=List.rev(List.rev_mapfl)lettail_recursive_mapifl=letrecinneracci=function|[]->List.revacc|hd::tl->(inner[@ocaml.tailcall])((fihd)::acc)(i+1)tlininner[]0lopenLwt.Infixletreciter_sfl=matchlwith|[]->Lwt.return_unit|x::l->Lwt.applyfx>>=fun()->iter_sflletiter_pfl=letts=tail_recursive_map(Lwt.applyf)linLwt.jointsletreciteri_sifl=matchlwith|[]->Lwt.return_unit|x::l->Lwt.apply(fi)x>>=fun()->iteri_s(i+1)flletiteri_sfl=iteri_s0flletiteri_pfl=letf'i=Lwt.apply(fi)inletts=tail_recursive_mapif'linLwt.jointsletmap_sfl=letrecinneracc=function|[]->List.revacc|>Lwt.return|hd::tl->Lwt.applyfhd>>=funr->(inner[@ocaml.tailcall])(r::acc)tlininner[]lletrec_collectacc=function|[]->List.revacc|>Lwt.return|t::ts->t>>=funi->(_collect[@ocaml.tailcall])(i::acc)tsletmap_pfl=letts=tail_recursive_map(Lwt.applyf)lin_collect[]tsletfilter_map_sfl=letrecinneracc=function|[]->List.revacc|>Lwt.return|hd::tl->Lwt.applyfhd>>=function|Somev->(inner[@ocaml.tailcall])(v::acc)tl|None->(inner[@ocaml.tailcall])acctlininner[]lletfilter_map_pfl=letrec_collect_optionalacc=function|[]->List.revacc|>Lwt.return|t::ts->t>>=function|Somev->(_collect_optional[@ocaml.tailcall])(v::acc)ts|None->(_collect_optional[@ocaml.tailcall])acctsinletts=tail_recursive_map(Lwt.applyf)lin_collect_optional[]tsletmapi_sfl=letrecinneracci=function|[]->List.revacc|>Lwt.return|hd::tl->Lwt.apply(fi)hd>>=funv->(inner[@ocaml.tailcall])(v::acc)(i+1)tlininner[]0lletmapi_pfl=letf'i=Lwt.apply(fi)inletts=tail_recursive_mapif'lin_collect[]tsletrecrev_map_append_saccfl=matchlwith|[]->Lwt.returnacc|x::l->Lwt.applyfx>>=funx->rev_map_append_s(x::acc)flletrev_map_sfl=rev_map_append_s[]flletrecrev_map_append_paccfl=matchlwith|[]->acc|x::l->rev_map_append_p(Lwt.applyfx>>=funx->acc>|=funl->x::l)flletrev_map_pfl=rev_map_append_pLwt.return_nilflletrecfold_left_sfaccl=matchlwith|[]->Lwt.returnacc|x::l->Lwt.apply(facc)x>>=funacc->(fold_left_s[@ocaml.tailcall])facclletfold_right_sflacc=letrecinnerfa=function|[]->Lwt.returna|hd::tl->(Lwt.apply(fhd)a)>>=funa'->(inner[@ocaml.tailcall])fa'tlininnerfacc(List.revl)letrecfor_all_sfl=matchlwith|[]->Lwt.return_true|x::l->Lwt.applyfx>>=function|true->(for_all_s[@ocaml.tailcall])fl|false->Lwt.return_falseletfor_all_pfl=map_pfl>>=funbl->List.for_all(funx->x)bl|>Lwt.returnletrecexists_sfl=matchlwith|[]->Lwt.return_false|x::l->Lwt.applyfx>>=function|true->Lwt.return_true|false->(exists_s[@ocaml.tailcall])flletexists_pfl=map_pfl>>=funbl->List.exists(funx->x)bl|>Lwt.returnletrecfind_sfl=matchlwith|[]->Lwt.failNot_found|x::l->Lwt.applyfx>>=function|true->Lwt.returnx|false->(find_s[@ocaml.tailcall])fllet_optionalizefx=fx>>=funb->ifbthenLwt.return(Somex)elseLwt.returnNoneletfilter_sfl=filter_map_s(_optionalizef)lletfilter_pfl=filter_map_p(_optionalizef)lletpartition_sfl=letrecinneracc1acc2=function|[]->Lwt.return(List.revacc1,List.revacc2)|hd::tl->Lwt.applyfhd>>=funb->ifbtheninner(hd::acc1)acc2tlelseinneracc1(hd::acc2)tlininner[][]lletpartition_pfl=letgx=Lwt.applyfx>>=funb->Lwt.return(b,x)inmap_pgl>>=funtl->letgroup1=tail_recursive_mapsnd@@List.filterfsttlinletgroup2=tail_recursive_mapsnd@@List.filter(funx->not@@fstx)tlinLwt.return(group1,group2)