From 30f7ac7551b0f1ee0978ce30d89e4276e67223fb Mon Sep 17 00:00:00 2001 From: Emmanuel Arrighi Date: Fri, 6 Feb 2026 14:28:56 +0100 Subject: [PATCH] CCResult(cleanup): sync CCResult with Stdlib.Result. --- src/core/CCResult.ml | 69 +++++++++++-------------------------------- src/core/CCResult.mli | 57 ++++++++++++----------------------- 2 files changed, 36 insertions(+), 90 deletions(-) diff --git a/src/core/CCResult.ml b/src/core/CCResult.ml index 69bbab60..b762becb 100644 --- a/src/core/CCResult.ml +++ b/src/core/CCResult.ml @@ -9,13 +9,7 @@ type 'a printer = Format.formatter -> 'a -> unit (** {2 Basics} *) -type nonrec (+'good, +'bad) result = ('good, 'bad) result = - | Ok of 'good - | Error of 'bad - -type (+'good, +'bad) t = ('good, 'bad) result = - | Ok of 'good - | Error of 'bad +include Result let return x = Ok x let fail s = Error s @@ -65,30 +59,14 @@ let opt_map f e = | Ok x -> Ok (Some x) | Error e -> Error e) -let map f e = - match e with - | Ok x -> Ok (f x) - | Error s -> Error s - -let map_err f e = - match e with - | Ok _ as res -> res - | Error y -> Error (f y) +let map_err = map_error let map2 f g e = match e with | Ok x -> Ok (f x) | Error s -> Error (g s) -let iter f e = - match e with - | Ok x -> f x - | Error _ -> () - -let iter_err f e = - match e with - | Ok _ -> () - | Error err -> f err +let iter_err = iter_error exception Get_error @@ -132,6 +110,13 @@ let flat_map f e = | Ok x -> f x | Error s -> Error s +[@@@iflt 5.4] + +let retract = function + | Ok v | Error v -> v + +[@@@endif] + let k_compose f g x = f x |> flat_map g let ( >=> ) = k_compose let ( <=< ) f g = g >=> f @@ -149,24 +134,11 @@ let compare ~err cmp a b = | _, Ok _ -> -1 | Error s, Error s' -> err s s' -let fold ~ok ~error x = - match x with - | Ok x -> ok x - | Error s -> error s - let fold_ok f acc r = match r with | Ok x -> f acc x | Error _ -> acc -let is_ok = function - | Ok _ -> true - | Error _ -> false - -let is_error = function - | Ok _ -> false - | Error _ -> true - (** {2 Wrappers} *) let guard f = try Ok (f ()) with e -> Error e @@ -185,18 +157,18 @@ let ( <*> ) f x = | Error s -> fail s | Ok f -> map f x -let join t = - match t with - | Ok (Ok o) -> Ok o - | Ok (Error e) -> Error e - | Error _ as e -> e +[@@@iflt 5.4] -let both x y = +let product x y = match x, y with | Ok o, Ok o' -> Ok (o, o') | Ok _, Error e -> Error e | Error e, _ -> Error e +[@@@endif] + +let both = product + (** {2 Collections} *) let map_l f l = @@ -331,19 +303,12 @@ end (** {2 Conversions} *) -let to_opt = function - | Ok x -> Some x - | Error _ -> None +let to_opt = to_option let of_opt = function | None -> Error "of_opt" | Some x -> Ok x -let to_seq e () = - match e with - | Ok x -> Seq.Cons (x, Seq.empty) - | Error _ -> Seq.Nil - let to_iter e k = match e with | Ok x -> k x diff --git a/src/core/CCResult.mli b/src/core/CCResult.mli index 5347b3fd..71304c5c 100644 --- a/src/core/CCResult.mli +++ b/src/core/CCResult.mli @@ -16,13 +16,7 @@ type 'a printer = Format.formatter -> 'a -> unit (** {2 Basics} *) -type nonrec (+'good, +'bad) result = ('good, 'bad) result = - | Ok of 'good - | Error of 'bad - -type (+'good, +'bad) t = ('good, 'bad) result = - | Ok of 'good - | Error of 'bad +include module type of Result val return : 'a -> ('a, 'err) t (** Successfully return a value. *) @@ -68,22 +62,15 @@ val opt_map : ('a -> ('b, 'c) t) -> 'a option -> ('b option, 'c) t (** Map a fallible operation through an option. @since 3.7 *) -val map : ('a -> 'b) -> ('a, 'err) t -> ('b, 'err) t -(** Map on success. *) - val map_err : ('err1 -> 'err2) -> ('a, 'err1) t -> ('a, 'err2) t -(** Map on the error variant. *) +(** Alias of [map_error] *) val map2 : ('a -> 'b) -> ('err1 -> 'err2) -> ('a, 'err1) t -> ('b, 'err2) t (** Like {!map}, but also with a function that can transform the error message in case of failure. *) -val iter : ('a -> unit) -> ('a, _) t -> unit -(** Apply the function only in case of [Ok]. *) - val iter_err : ('err -> unit) -> (_, 'err) t -> unit -(** Apply the function in case of [Error]. - @since 2.4 *) +(** Alias of {!iter_error} *) exception Get_error @@ -120,6 +107,13 @@ val catch : ('a, 'err) t -> ok:('a -> 'b) -> err:('err -> 'b) -> 'b val flat_map : ('a -> ('b, 'err) t) -> ('a, 'err) t -> ('b, 'err) t +[@@@iflt 5.4] + +val retract : ('a, 'a) t -> 'a +(** [retract r] collapse [r] to [v] if [r] is either [Ok v] or [Error v]. *) + +[@@@endif] + val k_compose : ('a -> ('b, 'err) t) -> ('b -> ('c, 'err) t) -> 'a -> ('c, 'err) t (** Kleisli composition. Monadic equivalent of {!CCFun.compose}. @@ -128,23 +122,11 @@ val k_compose : val equal : err:'err equal -> 'a equal -> ('a, 'err) t equal val compare : err:'err ord -> 'a ord -> ('a, 'err) t ord -val fold : ok:('a -> 'b) -> error:('err -> 'b) -> ('a, 'err) t -> 'b -(** [fold ~ok ~error e] opens [e] and, if [e = Ok x], returns - [ok x], otherwise [e = Error s] and it returns [error s]. *) - val fold_ok : ('a -> 'b -> 'a) -> 'a -> ('b, _) t -> 'a (** [fold_ok f acc r] will compute [f acc x] if [r=Ok x], and return [acc] otherwise, as if the result were a mere option. @since 1.2 *) -val is_ok : ('a, 'err) t -> bool -(** Return true if [Ok]. - @since 1.0 *) - -val is_error : ('a, 'err) t -> bool -(** Return true if [Error]. - @since 1.0 *) - (** {2 Wrappers} *) val guard : (unit -> 'a) -> ('a, exn) t @@ -172,15 +154,18 @@ val wrap3 : ('a -> 'b -> 'c -> 'd) -> 'a -> 'b -> 'c -> ('d, exn) t val pure : 'a -> ('a, 'err) t (** Synonym of {!return}. *) -val join : (('a, 'err) t, 'err) t -> ('a, 'err) t -(** [join t], in case of success, returns [Ok o] from [Ok (Ok o)]. Otherwise, - it fails with [Error e] where [e] is the unwrapped error of [t]. *) +[@@@iflt 5.4] -val both : ('a, 'err) t -> ('b, 'err) t -> ('a * 'b, 'err) t -(** [both a b], in case of success, returns [Ok (o, o')] with the ok values +val product : ('a, 'err) t -> ('b, 'err) t -> ('a * 'b, 'err) t +(** [product a b], in case of success, returns [Ok (o, o')] with the ok values of [a] and [b]. Otherwise, it fails, and the error of [a] is chosen over the error of [b] if both fail. *) +[@@@endif] + +val both : ('a, 'err) t -> ('b, 'err) t -> ('a * 'b, 'err) t +(** Alias of {!product} *) + (** {2 Infix} *) module Infix : sig @@ -279,7 +264,7 @@ end (** {2 Conversions} *) val to_opt : ('a, _) t -> 'a option -(** Convert a result to an option. *) +(** Alias of {!to_option} *) val of_opt : 'a option -> ('a, string) t (** [of_opt opt] converts [Some v] to [Ok v] and [None] to [Error "of_opt"].*) @@ -287,10 +272,6 @@ val of_opt : 'a option -> ('a, string) t val to_iter : ('a, _) t -> 'a iter (** @since 2.8 *) -val to_seq : ('a, _) t -> 'a Seq.t -(** Renamed from [to_std_seq] since 3.0. - @since 3.0 *) - type ('a, 'b) error = [ `Ok of 'a | `Error of 'b