From 3c06879debea2b572937c9aecf2c18c874f7e50a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Henry?= Date: Sun, 19 Nov 2017 14:59:47 +0100 Subject: [PATCH] Shell: add `Error_monad.{iter2_p,iteri2_p}` --- src/utils/error_monad.ml | 31 +++++++++++++++++++++++++++++++ src/utils/error_monad_sig.ml | 2 ++ 2 files changed, 33 insertions(+) diff --git a/src/utils/error_monad.ml b/src/utils/error_monad.ml index f13df0bd3..84d794c06 100644 --- a/src/utils/error_monad.ml +++ b/src/utils/error_monad.ml @@ -312,6 +312,37 @@ module Make() = struct | Ok (), Error exn | Error exn, Ok () -> Lwt.return (Error exn) + let rec iter2_p f l1 l2 = + match l1, l2 with + | [], [] -> return () + | [], _ | _, [] -> invalid_arg "Error_monad.iter2_p" + | x1 :: l1 , x2 :: l2 -> + let tx = f x1 x2 and tl = iter2_p f l1 l2 in + tx >>= fun tx_res -> + tl >>= fun tl_res -> + match tx_res, tl_res with + | Ok (), Ok () -> Lwt.return (Ok ()) + | Error exn1, Error exn2 -> Lwt.return (Error (exn1 @ exn2)) + | Ok (), Error exn + | Error exn, Ok () -> Lwt.return (Error exn) + + let iteri2_p f l1 l2 = + let rec iteri2_p i f l1 l2 = + match l1, l2 with + | [], [] -> return () + | [], _ | _, [] -> invalid_arg "Error_monad.iteri2_p" + | x1 :: l1 , x2 :: l2 -> + let tx = f i x1 x2 and tl = iteri2_p (i+1) f l1 l2 in + tx >>= fun tx_res -> + tl >>= fun tl_res -> + match tx_res, tl_res with + | Ok (), Ok () -> Lwt.return (Ok ()) + | Error exn1, Error exn2 -> Lwt.return (Error (exn1 @ exn2)) + | Ok (), Error exn + | Error exn, Ok () -> Lwt.return (Error exn) + in + iteri2_p 0 f l1 l2 + let rec fold_left_s f init l = match l with | [] -> return init diff --git a/src/utils/error_monad_sig.ml b/src/utils/error_monad_sig.ml index 9aa32acc7..229238197 100644 --- a/src/utils/error_monad_sig.ml +++ b/src/utils/error_monad_sig.ml @@ -118,6 +118,8 @@ module type S = sig (** A {!List.iter} in the monad *) val iter_s : ('a -> unit tzresult Lwt.t) -> 'a list -> unit tzresult Lwt.t val iter_p : ('a -> unit tzresult Lwt.t) -> 'a list -> unit tzresult Lwt.t + val iter2_p : ('a -> 'b -> unit tzresult Lwt.t) -> 'a list -> 'b list -> unit tzresult Lwt.t + val iteri2_p : (int -> 'a -> 'b -> unit tzresult Lwt.t) -> 'a list -> 'b list -> unit tzresult Lwt.t (** A {!List.map} in the monad *) val map_s : ('a -> 'b tzresult Lwt.t) -> 'a list -> 'b list tzresult Lwt.t