123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153(*****************************************************************************)(* *)(* 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. *)(* *)(*****************************************************************************)moduleMake(Trace:Sig.TRACE):Sig.MONADwithtype'errtrace:='errTrace.trace=structlet(>>=)=Lwt.(>>=)let[@inline]okv=Okvletok_unit=Ok()letok_none=OkNonelet[@inline]ok_somex=Ok(Somex)letok_nil=Ok[]letok_true=Oktrueletok_false=Okfalselet[@inline]errors=Error(Trace.makes)let[@inline]returnv=Lwt.return_okvletreturn_unit=Lwt.returnok_unitletreturn_none=Lwt.returnok_nonelet[@inline]return_somex=Lwt.return(Ok(Somex))letreturn_nil=Lwt.returnok_nilletreturn_true=Lwt.returnok_trueletreturn_false=Lwt.returnok_falselet[@inline]fails=Lwt.return_error@@Trace.makeslet(>>?)vf=matchvwithError_aserr->err|Okv->fvlet(>>=?)vf=v>>=functionError_aserr->Lwt.returnerr|Okv->fvlet(>>?=)vf=matchvwithError_ase->Lwt.returne|Okv->fvlet(>|?=)vf=matchvwithError_ase->Lwt.returne|Okv->fv>>=Lwt.return_oklet(>|=?)vf=v>>=?funv->Lwt.return_ok(fv)let(>|=)=Lwt.(>|=)let(>|?)vf=v>>?funv->Ok(fv)letjoin_p=Lwt.joinletall_p=Lwt.allletboth_p=Lwt.bothletrecjoin_e_errorstrace_acc=function|Ok_::ts->join_e_errorstrace_accts|Errortrace::ts->join_e_errors(Trace.conptrace_acctrace)ts|[]->Errortrace_accletrecjoin_e=function|[]->ok_unit|Ok()::ts->join_ets|Errortrace::ts->join_e_errorstracetsletall_ets=letrecauxacc=function|[]->Ok(List.revacc)|Okv::ts->aux(v::acc)ts|Errortrace::ts->join_e_errorstracetsinaux[]tsletboth_eab=match(a,b)with|(Oka,Okb)->Ok(a,b)|(Errorerr,Ok_)|(Ok_,Errorerr)->Errorerr|(Errorerra,Errorerrb)->Error(Trace.conperraerrb)letjoin_epts=all_pts>|=join_eletall_epts=all_pts>|=all_eletboth_epab=both_pab>|=fun(a,b)->both_eabletrecord_traceerrresult=matchresultwith|Ok_asres->res|Errortrace->Error(Trace.conserrtrace)lettraceerrf=f>>=function|Errortrace->Lwt.return_error(Trace.conserrtrace)|ok->Lwt.returnokletrecord_trace_evalmk_err=function|Errortrace->mk_err()>>?funerr->Error(Trace.conserrtrace)|ok->oklettrace_evalmk_errf=f>>=function|Errortrace->mk_err()>>=?funerr->Lwt.return_error(Trace.conserrtrace)|ok->Lwt.returnokleterror_unlesscondexn=ifcondthenok_unitelseerrorexnleterror_whencondexn=ifcondthenerrorexnelseok_unitletfail_unlesscondexn=ifcondthenreturn_unitelsefailexnletfail_whencondexn=ifcondthenfailexnelsereturn_unitletunlesscondf=ifcondthenreturn_unitelsef()letwhen_condf=ifcondthenf()elsereturn_unitletdont_waitexc_handlererr_handlerf=Lwt_utils.dont_waitexc_handler(fun()->f()>>=function|Ok()->Lwt.return_unit|Errortrace->err_handlertrace;Lwt.return_unit)end