All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.swoval.functional.Either Maven / Gradle / Ivy

There is a newer version: 2.1.12
Show newest version
package com.swoval.functional;

/**
 * Represents a value that can be one of two types. Inspired by Either,
 * it is right biased, but does not define all of the combinators that the scala version does.
 *
 * @param  The left value
 * @param  The right value
 */
public abstract class Either {
  private Either() {}

  /**
   * Returns the Left projection for the provided Either or throws an exception if the Either is
   * actually an instance of {@link com.swoval.functional.Either.Right}.
   *
   * @param either the either, assumed to be an instance of left, that will
   * @param  the left type of the either.
   * @param  the right type of the either.
   * @return a Left projection.
   * @throws NotLeftException if the value is a {@link com.swoval.functional.Either.Right}.
   */
  public static  Left leftProjection(final Either either)
      throws NotLeftException {
    if (either.isLeft()) return (Left) either;
    else throw new NotLeftException();
  }

  /**
   * Returns the Right projection for the provided Either or throws an exception if the Either is
   * actually an instance of {@link com.swoval.functional.Either.Left}.
   *
   * @param either the either, assumed to be an instance of left, that will
   * @param  the left type of the either.
   * @param  the right type of the either.
   * @return a Right projection.
   * @throws NotRightException if the value is a {@link com.swoval.functional.Either.Left}.
   */
  public static  Right rightProjection(final Either either)
      throws NotRightException {
    if (either.isRight()) return (Right) either;
    else throw new NotRightException();
  }

  /**
   * Check whether this is a Left projection.
   *
   * @return true if this is a Reft projection
   */
  public abstract boolean isLeft();

  /**
   * Check whether this is a Right projection.
   *
   * @return true if this is a Right projection
   */
  public abstract boolean isRight();

  /**
   * Get the right projected value of the either. This is unsafe to call without checking whether
   * the value is a right first.
   *
   * @return the wrapped value if is a right projection
   * @throws NotRightException if this is a left projection
   */
  public R get() {
    if (isRight()) return rightProjection(this).getValue();
    else throw new NotRightException();
  }

  /**
   * Get the right projected value of the either or a provided default value.
   *
   * @param either the either from which the method extracts the result if it is a {@link
   *     com.swoval.functional.Either.Right}.
   * @param t the default value
   * @param  the default type
   * @return the wrapped value if this is a right projection, otherwise the default
   */
  public static  T getOrElse(final Either either, final T t) {
    return either.isRight() ? either.get() : t;
  }

  @Override
  public abstract int hashCode();

  @Override
  public abstract boolean equals(final Object other);

  /**
   * Returns a left projected either.
   *
   * @param value the value to wrap
   * @param  the type of the left parameter of the result
   * @param  the type of the right parameter of the result
   * @param  a refinement type that allows us to wrap subtypes of L
   * @return A left projected either
   */
  public static  Either left(final T value) {
    return new Left<>((L) value);
  }

  /**
   * Returns a right projected either.
   *
   * @param value the value to wrap
   * @param  the type of the left parameter of the result
   * @param  the type of the right parameter of the result
   * @param  a refinement type that allows us to wrap subtypes of R
   * @return a right projected either.
   */
  public static  Either right(final T value) {
    return new Right<>((R) value);
  }

  /**
   * An error that is thrown if an attempt is made to project an Either to {@link
   * com.swoval.functional.Either.Left} when the object is actually an instance of {@link
   * com.swoval.functional.Either.Right}.
   */
  public static class NotLeftException extends RuntimeException {}

  /**
   * An error that is thrown if an attempt is made to project an Either to {@link
   * com.swoval.functional.Either.Right} when the object is actually an instance of {@link
   * com.swoval.functional.Either.Left}.
   */
  public static class NotRightException extends RuntimeException {}

  /**
   * A left projected {@link com.swoval.functional.Either}.
   *
   * @param  the left type
   * @param  the right type
   */
  public static final class Left extends Either {
    private final L value;

    Left(final L value) {
      this.value = value;
    }

    /**
     * Returns the wrapped value
     *
     * @return the wrapped value
     */
    public L getValue() {
      return value;
    }

    @Override
    public boolean isLeft() {
      return true;
    }

    @Override
    public boolean isRight() {
      return false;
    }

    @Override
    public String toString() {
      return "Left(" + value + ")";
    }

    @Override
    public boolean equals(Object other) {
      return other instanceof com.swoval.functional.Either.Left
          && this.value.equals(((com.swoval.functional.Either.Left) other).getValue());
    }

    @Override
    public int hashCode() {
      return value.hashCode();
    }
  }

  /**
   * A right projected {@link com.swoval.functional.Either}.
   *
   * @param  the left type
   * @param  the right type
   */
  public static final class Right extends Either {
    private final R value;

    Right(final R value) {
      this.value = value;
    }

    /**
     * Returns the wrapped value.
     *
     * @return the wrapped value.
     */
    public R getValue() {
      return value;
    }

    @Override
    public boolean isLeft() {
      return false;
    }

    @Override
    public boolean isRight() {
      return true;
    }

    @Override
    public String toString() {
      return "Right(" + value + ")";
    }

    @Override
    public boolean equals(Object other) {
      return other instanceof com.swoval.functional.Either.Right
          && this.value.equals(((com.swoval.functional.Either.Right) other).getValue());
    }

    @Override
    public int hashCode() {
      return value.hashCode();
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy