module Internal_result = struct type ('a, 'b) t = ('a, 'b) result = Ok of 'a | Error of 'b let return x = Ok x let error e = Error e let error_string s = Error (`Error_message s) let bind = Stdlib.Result.bind let ok = Result.ok module List = struct let map (xs : 'a list) ~(f : 'a -> ('b, 'c) t) : ('b list, 'c) t = let rec loop ?(acc = []) xs = match xs with | [] -> return (List.rev acc) | hd :: tl -> ( match f hd with | Ok x -> loop ~acc:(x :: acc) tl | Error e -> Error e) in loop xs let iteri ?(start = 0) (xs : 'a list) ~(f : int -> 'a -> (unit, 'b) t) : (unit, 'b) t = let rec loop ?(idx = start) xs = match xs with | [] -> return () | hd :: tl -> begin let res = f idx hd in match res with | Ok () -> loop ~idx:(idx + 1) tl | Error e -> Error e end in loop xs end module Let_syntax = struct let ( let* ) = Stdlib.Result.bind let ( let+ ) x f = Stdlib.Result.map f x end end include Internal_result