Interface Either<L,R>

Type Parameters:
L - the type of the left value
R - the type of the right value
All Known Implementing Classes:
Either.Left, Either.Right

@NullMarked public sealed interface Either<L,R> permits Either.Left<L,R>, Either.Right<L,R>
A disjoint union that is either a Either.Left or a Either.Right.

Either<L,R> is a neutral two-track type: neither side carries error semantics. Use it when a computation legitimately returns one of two value types without implying that one side is a failure. For error-handling use cases prefer Result, which is semantically opinionated (Ok = success, Err = failure) and offers richer recovery operations.

By convention, map, flatMap, and related operations act on the right side. Use swap() to flip the sides when you need to operate on the left.

This interface is @NullMarked: all values — left and right — are non-null by default.

  • Method Details

    • left

      static <L,R> Either<L,R> left(L value)
      Creates a Either.Left instance wrapping the given value.
      Type Parameters:
      L - the left type
      R - the right type
      Parameters:
      value - the non-null left value
      Returns:
      an Either containing the left value
      Throws:
      NullPointerException - if value is null
    • right

      static <L,R> Either<L,R> right(R value)
      Creates a Either.Right instance wrapping the given value.
      Type Parameters:
      L - the left type
      R - the right type
      Parameters:
      value - the non-null right value
      Returns:
      an Either containing the right value
      Throws:
      NullPointerException - if value is null
    • isLeft

      default boolean isLeft()
      Returns true if this is a Either.Left.
      Returns:
      true for Left, false for Right
    • isRight

      default boolean isRight()
      Returns true if this is a Either.Right.
      Returns:
      true for Right, false for Left
    • getLeft

      default L getLeft()
      Returns the left value.
      Returns:
      the left value
      Throws:
      NoSuchElementException - if this is a Either.Right
    • getRight

      default R getRight()
      Returns the right value.
      Returns:
      the right value
      Throws:
      NoSuchElementException - if this is a Either.Left
    • fold

      default <T> T fold(Function<? super L, ? extends T> onLeft, Function<? super R, ? extends T> onRight)
      Applies onLeft if this is Either.Left, or onRight if this is Either.Right, and returns the result.
      Type Parameters:
      T - the result type
      Parameters:
      onLeft - function applied to the left value
      onRight - function applied to the right value
      Returns:
      the result of whichever function was applied
    • map

      default <R2> Either<L,R2> map(Function<? super R, ? extends R2> mapper)
      Maps the right value using mapper, leaving a Either.Left unchanged.
      Type Parameters:
      R2 - the new right type
      Parameters:
      mapper - function applied to the right value
      Returns:
      a new Either with the mapped right value, or the original Left
    • mapLeft

      default <L2> Either<L2,R> mapLeft(Function<? super L, ? extends L2> mapper)
      Maps the left value using mapper, leaving a Either.Right unchanged.
      Type Parameters:
      L2 - the new left type
      Parameters:
      mapper - function applied to the left value
      Returns:
      a new Either with the mapped left value, or the original Right
    • flatMap

      default <R2> Either<L,R2> flatMap(Function<? super R, ? extends Either<? extends L, ? extends R2>> mapper)
      Applies mapper to the right value and returns the resulting Either, leaving a Either.Left unchanged. This is the monadic bind for the right track.
      Type Parameters:
      R2 - the new right type
      Parameters:
      mapper - function that returns an Either for the right value
      Returns:
      the result of mapper applied to the right value, or the original Left
    • swap

      default Either<R,L> swap()
      Swaps the two sides: Either.Left becomes Either.Right and vice-versa.
      Returns:
      an Either<R,L> with the sides swapped
    • peek

      default Either<L,R> peek(Consumer<? super R> action)
      Executes action if this is a Either.Right, then returns this unchanged.
      Parameters:
      action - consumer applied to the right value
      Returns:
      this Either
    • peekLeft

      default Either<L,R> peekLeft(Consumer<? super L> action)
      Executes action if this is a Either.Left, then returns this unchanged.
      Parameters:
      action - consumer applied to the left value
      Returns:
      this Either
    • toOption

      default Option<R> toOption()
      Converts this Either to an Option: Either.Right becomes Option.some(Object), Either.Left becomes Option.none().
      Returns:
      an Option containing the right value, or empty
    • toResult

      default Result<R,L> toResult()
      Converts this Either to a Result.

      Either.Right maps to Result.Ok; Either.Left maps to Result.Err. This is the inverse of Result.toEither().

      Returns:
      a Result<R, L> equivalent of this Either
    • toValidated

      default Validated<L,R> toValidated()
      Converts this Either to a Validated.

      Either.Right maps to Validated.valid(A); Either.Left maps to Validated.invalid(E). Useful for bringing a neutral Either into the error-accumulating validation world.

      Returns:
      a Validated<L, R> equivalent of this Either