123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2020 Nomadic Labs <contact@nomadic-labs.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)openLwt.Infix(* >>= *)let(>>?)=Result.bindlet(>>=?)vf=v>>=functionError_aserr->Lwt.returnerr|Okv->fvletok_nil=Ok[]letreturn_nil=Lwt.returnok_nillet[@inline]returnv=Lwt.return_okvletok_unit=Ok()letreturn_unit=Lwt.returnok_unitletrecmapfl=matchlwith|[]->ok_nil|h::t->fh>>?funrh->mapft>>?funrt->Ok(rh::rt)letmapifl=letrecmapifil=matchlwith|[]->ok_nil|h::t->fih>>?funrh->mapif(i+1)t>>?funrt->Ok(rh::rt)inmapif0lletrecmap_sfl=matchlwith|[]->return_nil|h::t->fh>>=?funrh->map_sft>>=?funrt->return(rh::rt)letmapi_sfl=letrecmapi_sfil=matchlwith|[]->return_nil|h::t->fih>>=?funrh->mapi_sf(i+1)t>>=?funrt->return(rh::rt)inmapi_sf0lletrecrev_map_append_saccf=function|[]->returnacc|hd::tl->fhd>>=?funv->rev_map_append_s(v::acc)ftlletrev_map_sfl=rev_map_append_s[]flletrecmap_pfl=matchlwith|[]->return_nil|x::l->(lettx=fxandtl=map_pflintx>>=funx->tl>>=funl->match(x,l)with|Okx,Okl->Lwt.return_ok(x::l)|Errortrace1,Errortrace2->Lwt.return_error(trace1@trace2)|Ok_,Errortrace|Errortrace,Ok_->Lwt.return_errortrace)letmapi_pfl=letrecmapi_pfil=matchlwith|[]->return_nil|x::l->(lettx=fixandtl=mapi_pf(i+1)lintx>>=funx->tl>>=funl->match(x,l)with|Okx,Okl->Lwt.return_ok(x::l)|Errortrace1,Errortrace2->Lwt.return_error(trace1@trace2)|Ok_,Errortrace|Errortrace,Ok_->Lwt.return_errortrace)inmapi_pf0lletrecmap2_sfl1l2=match(l1,l2)with|[],[]->return_nil|_::_,[]|[],_::_->invalid_arg"Error_monad.map2_s"|h1::t1,h2::t2->fh1h2>>=?funrh->map2_sft1t2>>=?funrt->return(rh::rt)letmapi2_sfl1l2=letrecmapi2_sifl1l2=match(l1,l2)with|[],[]->return_nil|_::_,[]|[],_::_->invalid_arg"Error_monad.mapi2_s"|h1::t1,h2::t2->fih1h2>>=?funrh->mapi2_s(i+1)ft1t2>>=?funrt->return(rh::rt)inmapi2_s0fl1l2letrecmap2fl1l2=match(l1,l2)with|[],[]->ok_nil|_::_,[]|[],_::_->invalid_arg"Error_monad.map2"|h1::t1,h2::t2->fh1h2>>?funrh->map2ft1t2>>?funrt->Ok(rh::rt)letmapi2fl1l2=letrecmapi2ifl1l2=match(l1,l2)with|[],[]->ok_nil|_::_,[]|[],_::_->invalid_arg"Error_monad.mapi2"|h1::t1,h2::t2->fih1h2>>?funrh->mapi2(i+1)ft1t2>>?funrt->Ok(rh::rt)inmapi20fl1l2letrecfilter_map_sfl=matchlwith|[]->return_nil|h::t->(fh>>=?function|None->filter_map_sft|Somerh->filter_map_sft>>=?funrt->return(rh::rt))letrecfilter_map_pfl=matchlwith|[]->return_nil|h::t->(letth=fhandtt=filter_map_pftinth>>=?function|None->tt|Somerh->tt>>=?funrt->return(rh::rt))letrecfilterfl=matchlwith|[]->ok_nil|h::t->(fh>>?function|true->filterft>>?funt->Ok(h::t)|false->filterft)letrecfilter_sfl=matchlwith|[]->return_nil|h::t->(fh>>=?function|false->filter_sft|true->filter_sft>>=?funt->return(h::t))letrecfilter_pfl=matchlwith|[]->return_nil|h::t->(letjh=fhandt=filter_pftinjh>>=?functionfalse->t|true->t>>=?funt->return(h::t))letreciterfl=matchlwith[]->ok_unit|h::t->fh>>?fun()->iterftletreciter_sfl=matchlwith[]->return_unit|h::t->fh>>=?fun()->iter_sftletreciter_pfl=matchlwith|[]->return_unit|x::l->(lettx=fxandtl=iter_pflintx>>=funtx_res->tl>>=funtl_res->match(tx_res,tl_res)with|Ok(),Ok()->Lwt.return_ok()|Errortrace1,Errortrace2->Lwt.return_error(trace1@trace2)|Ok(),Errortrace|Errortrace,Ok()->Lwt.return_errortrace)letiteri_pfl=letreciteri_pifl=matchlwith|[]->return_unit|x::l->(lettx=fixandtl=iteri_p(i+1)flintx>>=funtx_res->tl>>=funtl_res->match(tx_res,tl_res)with|Ok(),Ok()->Lwt.returnok_unit|Errortrace1,Errortrace2->Lwt.return_error(trace1@trace2)|Ok(),Errortrace|Errortrace,Ok()->Lwt.return_errortrace)initeri_p0flletreciter2_pfl1l2=match(l1,l2)with|[],[]->return_unit|[],_|_,[]->invalid_arg"Error_monad.iter2_p"|x1::l1,x2::l2->(lettx=fx1x2andtl=iter2_pfl1l2intx>>=funtx_res->tl>>=funtl_res->match(tx_res,tl_res)with|Ok(),Ok()->Lwt.return_ok()|Errortrace1,Errortrace2->Lwt.return_error(trace1@trace2)|Ok(),Errortrace|Errortrace,Ok()->Lwt.return_errortrace)letiteri2_pfl1l2=letreciteri2_pifl1l2=match(l1,l2)with|[],[]->return_unit|[],_|_,[]->invalid_arg"Error_monad.iteri2_p"|x1::l1,x2::l2->(lettx=fix1x2andtl=iteri2_p(i+1)fl1l2intx>>=funtx_res->tl>>=funtl_res->match(tx_res,tl_res)with|Ok(),Ok()->Lwt.return_ok()|Errortrace1,Errortrace2->Lwt.return_error(trace1@trace2)|Ok(),Errortrace|Errortrace,Ok()->Lwt.return_errortrace)initeri2_p0fl1l2letrecfold_left_sfinitl=matchlwith|[]->returninit|h::t->finith>>=?funacc->fold_left_sfacctletrecfold_right_sflinit=matchlwith|[]->returninit|h::t->fold_right_sftinit>>=?funacc->fhacc