From 34cfbd5cdc4c2d05bfc9abd80272ce4d9e52d719 Mon Sep 17 00:00:00 2001 From: Kento Okura Date: Sat, 22 Aug 2026 15:09:25 +0200 Subject: [PATCH] Add Eio.Fiber.List.partition_map --- lib_eio/core/eio__core.mli | 5 +++++ lib_eio/core/fiber.ml | 1 + tests/fiber.md | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/lib_eio/core/eio__core.mli b/lib_eio/core/eio__core.mli index dbcd4fa06..19b449635 100644 --- a/lib_eio/core/eio__core.mli +++ b/lib_eio/core/eio__core.mli @@ -350,6 +350,11 @@ module Fiber : sig invocations of [f] are run concurrently in separate fibers. @param max_fibers Maximum number of fibers to run concurrently *) + val partition_map : ?max_fibers:int -> ('a -> ('b, 'c) Either.t) -> 'a list -> 'b list * 'c list + (** [partition_map f x] is like [List.partition_map f x] except that the + invocations of [f] are run concurrently in separate fibers. + @param max_fibers Maximum number of fibers to run concurrently *) + val iter : ?max_fibers:int -> ('a -> unit) -> 'a list -> unit (** [iter f x] is like [List.iter f x] except that the invocations of [f] are run concurrently in separate fibers. diff --git a/lib_eio/core/fiber.ml b/lib_eio/core/fiber.ml index 1e241606e..97123d909 100644 --- a/lib_eio/core/fiber.ml +++ b/lib_eio/core/fiber.ml @@ -260,6 +260,7 @@ module List = struct aux items let map ?max_fibers fn = filter_map ?max_fibers (fun x -> Some (fn x)) + let partition_map ?max_fibers fn items = List.partition_map Fun.id (map ?max_fibers fn items) let filter ?max_fibers fn = filter_map ?max_fibers (fun x -> if fn x then Some x else None) let iter ?(max_fibers=max_int) fn items = diff --git a/tests/fiber.md b/tests/fiber.md index ad42a54fe..ade4da6c8 100644 --- a/tests/fiber.md +++ b/tests/fiber.md @@ -452,6 +452,10 @@ let string_even x = let crash_on_three x = if x = 3 then failwith "Simulated error" else string_even x + +let even_or_odd x = + if is_even x then Either.Right (string_of_int x) + else Either.Left (string_of_int x) ``` ```ocaml @@ -502,6 +506,22 @@ let crash_on_three x = - : unit = () ``` +```ocaml +# Eio_mock.Backend.run @@ fun () -> + Fiber.List.partition_map (process even_or_odd) [1; 2; 3; 4] + |> traceln "%a" Fmt.Dump.(pair (list string) (list string));; ++Start 1 ++Start 2 ++Start 3 ++Start 4 ++Finished 1 ++Finished 2 ++Finished 3 ++Finished 4 ++(["1"; "3"], ["2"; "4"]) +- : unit = () +``` + If any fiber raises, everything is cancelled: ```ocaml