diff --git a/src/core/CCList.ml b/src/core/CCList.ml index 82eb60a9..ebdf7cea 100644 --- a/src/core/CCList.ml +++ b/src/core/CCList.ml @@ -811,6 +811,48 @@ let filter_map f l = [ 1; 2; 3; 4; 5; 6 ]) *) +let keep_some l = filter_map (fun x->x) l + +let keep_ok l = + filter_map + (function + | Result.Ok x -> Some x + | Result.Error _ -> None) + l + +let all_some l = + try Some (map (function Some x -> x | None -> raise Exit) l) + with Exit -> None + +(*$= + (Some []) (all_some []) + (Some [1;2;3]) (all_some [Some 1; Some 2; Some 3]) + None (all_some [Some 1; None; None; Some 4]) +*) + +let all_ok l = + let err = ref None in + try + Result.Ok + (map + (function Result.Ok x -> x | Error e -> err := Some e; raise Exit) + l) + with Exit -> + begin match !err with + | None -> assert false + | Some e -> Result.Error e + end + +(*$inject + open Result +*) + +(*$= + (Ok []) (all_ok []) + (Ok [1;2;3]) (all_ok [Ok 1; Ok 2; Ok 3]) + (Error "e2") (all_ok [Ok 1; Error "e2"; Error "e3"; Ok 4]) +*) + let mem ?(eq=(=)) x l = let rec search eq x l = match l with | [] -> false diff --git a/src/core/CCList.mli b/src/core/CCList.mli index 686d154c..65da03b0 100644 --- a/src/core/CCList.mli +++ b/src/core/CCList.mli @@ -247,6 +247,26 @@ val remove : ?eq:('a -> 'a -> bool) -> x:'a -> 'a t -> 'a t val filter_map : ('a -> 'b option) -> 'a t -> 'b t (** Map and remove elements at the same time *) +val keep_some : 'a option t -> 'a t +(** [filter_some l] retains only elements of the form [Some x]. + Same as [filter_map CCFun.id] + @since NEXT_RELEASE *) + +val keep_ok : ('a, _) Result.result t -> 'a t +(** [filter_some l] retains only elements of the form [Some x]. + Same as [filter_map CCFun.id] + @since NEXT_RELEASE *) + +val all_some : 'a option t -> 'a t option +(** [all_some l] returns [Some l'] if all elements of [l] are of the form [Some x], + or [None] otherwise. + @since NEXT_RELEASE *) + +val all_ok : ('a, 'err) Result.result t -> ('a t, 'err) Result.result +(** [all_ok l] returns [Ok l'] if all elements of [l] are of the form [Ok x], + or [Error e] otherwise (with the first error met). + @since NEXT_RELEASE *) + val sorted_merge : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list (** Merges elements from both sorted list *)