Class Result<S,F>

java.lang.Object
com.guinetik.corefun.Result<S,F>
Type Parameters:
S - the type of the success value
F - the type of the failure value

public abstract class Result<S,F> extends Object
A functional container representing either a success or failure outcome.

Result is an Either-style monad that encapsulates either a successful value or an error, providing a functional approach to error handling without exceptions. This eliminates the need for null checks and exception handling in business logic, promoting cleaner, more composable code.

Key Features

Example Usage


 Result<User, String> result = findUser(id);

 // Pattern matching with fold
 String message = result.fold(
     error -> "Error: " + error,
     user -> "Found: " + user.getName()
 );

 // Chaining operations
 Result<String, String> greeting = result
     .map(user -> user.getName())
     .map(name -> "Hello, " + name);

 // Validation
 Result<Integer, String> validAge = Result.success(age)
     .validate(a -> a >= 0 && a <= 150, a -> "Invalid age: " + a);

 // Recovery from errors
 Result<User, String> userOrGuest = findUser(id)
     .recover(error -> Result.success(guestUser));
 
Since:
0.1.0
Author:
Guinetik <guinetik@gmail.com>
See Also:
  • Method Summary

    Modifier and Type
    Method
    Description
    static <S, F> Result<S,F>
    failure(F error)
    Creates a failed Result containing the given error.
    abstract <T> Result<T,F>
    flatMap(Function<? super S,Result<T,F>> mapper)
    Transforms the success value with a function that returns a Result.
    abstract <R> R
    fold(Function<? super F,? extends R> onFailure, Function<? super S,? extends R> onSuccess)
    Applies one of two functions depending on the Result state.
    abstract S
    get()
    Gets the success value.
    abstract F
    Gets the failure value.
    abstract S
    getOrElse(S defaultValue)
    Returns the success value or a default if this is a failure.
    abstract S
    getOrElseGet(Supplier<? extends S> supplier)
    Returns the success value or computes a default if this is a failure.
    abstract boolean
    Returns true if this Result represents a failure.
    abstract boolean
    Returns true if this Result represents a success.
    abstract <T> Result<T,F>
    map(Function<? super S,? extends T> mapper)
    Transforms the success value using the provided function.
    abstract <E> Result<S,E>
    mapFailure(Function<? super F,? extends E> mapper)
    Transforms the failure value using the provided function.
    abstract Result<S,F>
    peek(Consumer<Object> observer)
    Performs an action on the value (success or failure) without altering the Result.
    abstract Result<S,F>
    peekFailure(Consumer<? super F> action)
    Performs an action on the failure value if present.
    abstract Result<S,F>
    peekSuccess(Consumer<? super S> action)
    Performs an action on the success value if present.
    abstract Result<S,F>
    recover(Function<? super F,Result<S,F>> handler)
    Recovers from a failure by applying a function that returns a new Result.
    static <S, F> Result<List<S>,F>
    sequence(List<Result<S,F>> results)
    Converts a list of Results into a Result of a list.
    static <S, F> Result<S,F>
    success(S value)
    Creates a successful Result containing the given value.
    static <T, S, F> Result<List<S>,F>
    traverse(List<T> items, Function<? super T,Result<S,F>> mapper)
    Applies a function to each element and sequences the results.
    abstract Result<S,F>
    validate(Function<? super S,Boolean> predicate, Function<? super S,? extends F> failureProducer)
    Validates the success value against a predicate.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • success

      public static <S, F> Result<S,F> success(S value)
      Creates a successful Result containing the given value.
      Type Parameters:
      S - success type
      F - failure type
      Parameters:
      value - the success value
      Returns:
      a successful Result
    • failure

      public static <S, F> Result<S,F> failure(F error)
      Creates a failed Result containing the given error.
      Type Parameters:
      S - success type
      F - failure type
      Parameters:
      error - the failure value
      Returns:
      a failed Result
    • isSuccess

      public abstract boolean isSuccess()
      Returns true if this Result represents a success.
      Returns:
      true if success, false if failure
    • isFailure

      public abstract boolean isFailure()
      Returns true if this Result represents a failure.
      Returns:
      true if failure, false if success
    • get

      public abstract S get()
      Gets the success value. Throws if this is a failure.
      Returns:
      the success value
      Throws:
      IllegalStateException - if this is a failure
    • getError

      public abstract F getError()
      Gets the failure value. Throws if this is a success.
      Returns:
      the failure value
      Throws:
      IllegalStateException - if this is a success
    • fold

      public abstract <R> R fold(Function<? super F,? extends R> onFailure, Function<? super S,? extends R> onSuccess)
      Applies one of two functions depending on the Result state. This is the primary way to extract values from a Result.

      Example:

      
       String message = result.fold(
           error -> "Failed: " + error,
           value -> "Success: " + value
       );
       
      Type Parameters:
      R - the return type
      Parameters:
      onFailure - function to apply if failure
      onSuccess - function to apply if success
      Returns:
      the result of applying the appropriate function
    • map

      public abstract <T> Result<T,F> map(Function<? super S,? extends T> mapper)
      Transforms the success value using the provided function. If this is a failure, returns a new failure with the same error.
      Type Parameters:
      T - the new success type
      Parameters:
      mapper - function to transform the success value
      Returns:
      a new Result with the transformed value
    • flatMap

      public abstract <T> Result<T,F> flatMap(Function<? super S,Result<T,F>> mapper)
      Transforms the success value with a function that returns a Result. Useful for chaining operations that might fail.

      Example:

      
       Result<User, String> user = findUser(id);
       Result<Account, String> account = user.flatMap(u -> findAccount(u.getAccountId()));
       
      Type Parameters:
      T - the new success type
      Parameters:
      mapper - function that returns a Result
      Returns:
      the Result from the mapper, or a failure
    • mapFailure

      public abstract <E> Result<S,E> mapFailure(Function<? super F,? extends E> mapper)
      Transforms the failure value using the provided function.
      Type Parameters:
      E - the new failure type
      Parameters:
      mapper - function to transform the failure value
      Returns:
      a new Result with the transformed failure
    • getOrElse

      public abstract S getOrElse(S defaultValue)
      Returns the success value or a default if this is a failure.
      Parameters:
      defaultValue - the default to return on failure
      Returns:
      success value or default
    • getOrElseGet

      public abstract S getOrElseGet(Supplier<? extends S> supplier)
      Returns the success value or computes a default if this is a failure.
      Parameters:
      supplier - supplies the default value
      Returns:
      success value or computed default
    • recover

      public abstract Result<S,F> recover(Function<? super F,Result<S,F>> handler)
      Recovers from a failure by applying a function that returns a new Result.

      Example:

      
       Result<User, String> user = findUser(id)
           .recover(error -> findGuestUser());
       
      Parameters:
      handler - function to handle the failure
      Returns:
      this if success, or the result of the handler
    • validate

      public abstract Result<S,F> validate(Function<? super S,Boolean> predicate, Function<? super S,? extends F> failureProducer)
      Validates the success value against a predicate. If validation fails, produces a failure using the provided function.
      Parameters:
      predicate - condition to test
      failureProducer - produces failure value if predicate fails
      Returns:
      this if valid, or a failure
    • peek

      public abstract Result<S,F> peek(Consumer<Object> observer)
      Performs an action on the value (success or failure) without altering the Result.
      Parameters:
      observer - consumer that receives the value
      Returns:
      this Result unchanged
    • peekSuccess

      public abstract Result<S,F> peekSuccess(Consumer<? super S> action)
      Performs an action on the success value if present.
      Parameters:
      action - consumer for the success value
      Returns:
      this Result unchanged
    • peekFailure

      public abstract Result<S,F> peekFailure(Consumer<? super F> action)
      Performs an action on the failure value if present.
      Parameters:
      action - consumer for the failure value
      Returns:
      this Result unchanged
    • sequence

      public static <S, F> Result<List<S>,F> sequence(List<Result<S,F>> results)
      Converts a list of Results into a Result of a list. Returns the first failure encountered, or a success containing all values.

      Example:

      
       List<Result<Integer, String>> results = List.of(
           Result.success(1),
           Result.success(2),
           Result.success(3)
       );
       Result<List<Integer>, String> combined = Result.sequence(results);
       // Success[[1, 2, 3]]
      
       List<Result<Integer, String>> withFailure = List.of(
           Result.success(1),
           Result.failure("oops"),
           Result.success(3)
       );
       Result<List<Integer>, String> failed = Result.sequence(withFailure);
       // Failure[oops]
       
      Type Parameters:
      S - the success type
      F - the failure type
      Parameters:
      results - the list of Results to sequence
      Returns:
      a Result containing all success values, or the first failure
    • traverse

      public static <T, S, F> Result<List<S>,F> traverse(List<T> items, Function<? super T,Result<S,F>> mapper)
      Applies a function to each element and sequences the results. This is equivalent to mapping each element to a Result and then sequencing.

      Example:

      
       List<String> inputs = List.of("1", "2", "3");
       Result<List<Integer>, String> parsed = Result.traverse(inputs, s -> {
           try {
               return Result.success(Integer.parseInt(s));
           } catch (NumberFormatException e) {
               return Result.failure("Invalid number: " + s);
           }
       });
       // Success[[1, 2, 3]]
      
       List<String> mixed = List.of("1", "bad", "3");
       Result<List<Integer>, String> failed = Result.traverse(mixed, s -> ...);
       // Failure[Invalid number: bad]
       
      Type Parameters:
      T - the input element type
      S - the success type
      F - the failure type
      Parameters:
      items - the list of items to traverse
      mapper - function that converts each item to a Result
      Returns:
      a Result containing all success values, or the first failure