123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127(** Re-export for compatibility with 4.02. *)type('a,'b)result=('a,'b)Result.result=Okof'a|Errorof'b(** The [result] type and a bind operator. This module is meant to be opened. *)moduleResultMonad=struct(** Re-export for compat *)type('a,'b)result=('a,'b)Result.result=Okof'a|Errorof'bletmap_errorf=functionOk_asok->ok|Errore->Error(fe)letof_option~error=functionSomex->Okx|None->Errorerrorletbindmf=matchmwithOkx->fx|Error_ase->elet(>>=)=bindend(** A bind operator for the [option] type. This module is meant to be opened. *)moduleOptionMonad=struct(* The error case become [None], the error value is ignored. *)letof_result=functionResult.Okx->Somex|Error_->Noneletreturnx=Somexletbindmf=matchmwithSomex->fx|None->Nonelet(>>=)=bindendmoduleEitherMonad=structtype('a,'b)t=Leftof'a|Rightof'bletreturnx=Rightxletreturn_leftx=Leftxletbindmf=matchmwithRightx->fx|Lefty->Leftyletbind_leftmf=matchmwithLeftx->fx|Righty->Rightylet(>>=)=bindletof_option~left=functionSomex->Rightx|None->Leftleftletof_result=functionResult.Okx->Right x|Errory->LeftyendmoduleList=Odoc_listmoduleOption=structletmapf=functionNone->None|Somex->Some(fx)letis_some=functionNone->false|Some_->trueendmoduleResult=structincludeResultletjoin=functionOkr->r|Error_ase->eendmoduleFun=structexceptionFinally_raisedofexnletprotect~(finally:unit->unit)work=letfinally_no_exn()=tryfinally()withe->raise(Finally_raisede)inmatchwork()with|result->finally_no_exn();result|exceptionwork_exn->finally_no_exn();raisework_exnendmoduleTree=TreemoduleForest=Tree.ForestmoduleJson=JsonmoduleIo_utils=struct(** [with_open_*] are resource safe wrappers around opening and closing
channels. They are equivalent to the same functions in OCaml 4.14's
[In_channel] and [Out_channel]. *)let_with_resourceres~closef=Fun.protect~finally:(fun()->closeres)(fun()->fres)letwith_open_infnamef=_with_resource(open_infname)~close:close_in_noerrfletwith_open_in_binfnamef=_with_resource(open_in_binfname)~close:close_in_noerrf(** Read a file line-by-line by folding [f]. *)letfold_linesfnamefacc=_with_resource(open_infname)~close:close_in_noerr(funic->letrecloopacc=matchinput_lineicwith|exceptionEnd_of_file->acc|line->loop(flineacc)inloopacc)(** Read a file as a list of lines. *)letread_linesfname=List.rev(fold_linesfname(funlineacc->line::acc)[])letwith_open_outfnamef=_with_resource(open_outfname)~close:close_out_noerrfletwith_open_out_binfnamef=_with_resource(open_out_binfname)~close:close_out_noerrf(** Like [with_open_out] but operate on a [Format] buffer. *)letwith_formatter_outfnamef=with_open_outfname(funoc->f(Format.formatter_of_out_channeloc))(** Shortcuts for composing [with_open_*] functions and [Marshal]. *)letmarshalfnamev=with_open_out_binfname(funoc->Marshal.to_channelocv[])letunmarshalfname=with_open_in_binfnameMarshal.from_channelendincludeAstring