<commit_before>/**    / \____  _    ______   _____ / \____   ____  _____
 *    /  \__  \/ \  / \__  \ /  __//  \__  \ /    \/ __  \   Javaslang
 *  _/  // _\  \  \/  / _\  \\_  \/  // _\  \  /\  \__/  /   Copyright 2014-2015 <NAME>
 * /___/ \_____/\____/\_____/____/\___\_____/_/  \_/____/    Licensed under the Apache License, Version 2.0
 */
package javaslang.control;

import javaslang.ValueObject;
import javaslang.control.Valences.Bivalent;

import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * Either represents a value of two possible types. An Either is either a {@link javaslang.control.Left} or a
 * {@link javaslang.control.Right}.
 * <p>
 * It is possible to project an Either to a Left or a Right. Both cases can be further processed with control operations
 * map, flatMap, filter.
 * <p>
 * If the given Either is a Right and projected to a Left, the Left operations have no effect on the Right value.<br>
 * If the given Either is a Left and projected to a Right, the Right operations have no effect on the Left value.<br>
 * If a Left is projected to a Left or a Right is projected to a Right, the operations have an effect.
 * <p>
 * <strong>Example:</strong> A compute() function, which results either in an Integer value (in the case of success) or
 * in an error message of type String (in the case of failure). By convention the success case is Right and the failure
 * is Left.
 * 
 * <pre>
 * <code>
 * Either&lt;String,Integer&gt; value = compute().right().map(i -&gt; i * 2);
 * </code>
 * </pre>
 * 
 * If the result of compute() is Right(1), the value is Right(2).<br>
 * If the result of compute() is Left("error), the value is Left("error").
 *
 * @param <L> The type of a Left value of the Either.
 * @param <R> The type of a Right value of the Either.
 * @since 1.0.0
 */
// DEV-NOTE: Either is no Monad and no Functor in the sense of javaslang.Algebra.*
public interface Either<L, R> extends ValueObject {

    long serialVersionUID = 1L;

	boolean isLeft();

	boolean isRight();

	default LeftProjection<L, R> left() {
		return new LeftProjection<>(this);
	}

	default RightProjection<L, R> right() {
		return new RightProjection<>(this);
	}

	// -- Object.*

	@Override
	boolean equals(Object o);

	@Override
	int hashCode();

	@Override
	String toString();

	// -- Left/Right projections

	final class LeftProjection<L, R> implements Bivalent<L, R> {

		private final Either<L, R> either;

		LeftProjection(Either<L, R> either) {
			this.either = either;
		}

		public L get() {
			if (either.isLeft()) {
				return asLeft();
			} else {
				throw new NoSuchElementException("Either.left().get() on Right");
			}
		}

		@Override
		public L orElse(L other) {
			return either.isLeft() ? asLeft() : other;
		}

		@Override
		public L orElseGet(Function<? super R, ? extends L> other) {
			if (either.isLeft()) {
				return asLeft();
			} else {
				return other.apply(asRight());
			}
		}

		@Override
		public void orElseRun(Consumer<? super R> action) {
			if (either.isRight()) {
				action.accept(asRight());
			}
		}

		@Override
		public <X extends Throwable> L orElseThrow(Function<? super R, X> exceptionFunction) throws X {
			if (either.isLeft()) {
				return asLeft();
			} else {
				throw exceptionFunction.apply(asRight());
			}
		}

		@Override
		public Option<L> toOption() {
			if (either.isLeft()) {
				return new Some<>(asLeft());
			} else {
				return None.instance();
			}
		}

		@Override
		public Either<L, R> toEither() {
			return either;
		}

		public Option<Either<L, R>> filter(Predicate<? super L> predicate) {
			Objects.requireNonNull(predicate);
			if (either.isLeft() && predicate.test(asLeft())) {
				return new Some<>(either);
			} else {
				return None.instance();
			}
		}

		public void forEach(Consumer<? super L> action) {
			Objects.requireNonNull(action);
			if (either.isLeft()) {
				action.accept(asLeft());
			}
		}

		@SuppressWarnings("unchecked")
		public <U> Either<U, R> map(Function<? super L, ? extends U> mapper) {
			Objects.requireNonNull(mapper);
			if (either.isLeft())
				return new Left<>(mapper.apply(asLeft()));
			else {
				return (Either<U,R>) either;
			}
		}

		@SuppressWarnings("unchecked")
		public <U> Either<U, R> flatMap(Function<? super L, ? extends Either<U, R>> mapper) {
			Objects.requireNonNull(mapper);
			if (either.isLeft()) {
				return mapper.apply(asLeft());
			} else {
				return (Either<U,R>) either;
			}
		}

		@Override
		public boolean equals(Object obj) {
			return (obj == this) || (obj instanceof LeftProjection && Objects.equals(either, ((LeftProjection<?, ?>) obj).either));
		}

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

		@Override
		public String toString() {
			return String.format("LeftProjection(%s)", either);
		}

		private L asLeft() {
			return ((Left<L, R>) either).left;
		}

		private R asRight() {
			return ((Right<L, R>) either).right;
		}
	}
<commit_msg>Towards #97: adds since javadoc parameter to left and right projection<commit_after>/**    / \____  _    ______   _____ / \____   ____  _____
 *    /  \__  \/ \  / \__  \ /  __//  \__  \ /    \/ __  \   Javaslang
 *  _/  // _\  \  \/  / _\  \\_  \/  // _\  \  /\  \__/  /   Copyright 2014-2015 <NAME>
 * /___/ \_____/\____/\_____/____/\___\_____/_/  \_/____/    Licensed under the Apache License, Version 2.0
 */
package javaslang.control;

import javaslang.ValueObject;
import javaslang.control.Valences.Bivalent;

import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * Either represents a value of two possible types. An Either is either a {@link javaslang.control.Left} or a
 * {@link javaslang.control.Right}.
 * <p>
 * It is possible to project an Either to a Left or a Right. Both cases can be further processed with control operations
 * map, flatMap, filter.
 * <p>
 * If the given Either is a Right and projected to a Left, the Left operations have no effect on the Right value.<br>
 * If the given Either is a Left and projected to a Right, the Right operations have no effect on the Left value.<br>
 * If a Left is projected to a Left or a Right is projected to a Right, the operations have an effect.
 * <p>
 * <strong>Example:</strong> A compute() function, which results either in an Integer value (in the case of success) or
 * in an error message of type String (in the case of failure). By convention the success case is Right and the failure
 * is Left.
 *
 * <pre>
 * <code>
 * Either&lt;String,Integer&gt; value = compute().right().map(i -&gt; i * 2);
 * </code>
 * </pre>
 *
 * If the result of compute() is Right(1), the value is Right(2).<br>
 * If the result of compute() is Left("error), the value is Left("error").
 *
 * @param <L> The type of the Left value of an Either.
 * @param <R> The type of the Right value of an Either.
 * @since 1.0.0
 */
// DEV-NOTE: Either is no Monad and no Functor in the sense of javaslang.Algebra.*
public interface Either<L, R> extends ValueObject {

    long serialVersionUID = 1L;

	boolean isLeft();

	boolean isRight();

	default LeftProjection<L, R> left() {
		return new LeftProjection<>(this);
	}

	default RightProjection<L, R> right() {
		return new RightProjection<>(this);
	}

	// -- Object.*

	@Override
	boolean equals(Object o);

	@Override
	int hashCode();

	@Override
	String toString();

	// -- Left/Right projections

	/**
     * A left projection of an either.
     *
     * @param <L> The type of the Left value of an Either.
     * @param <R> The type of the Right value of an Either.
     * @since 1.0.0
     */
 	final class LeftProjection<L, R> implements Bivalent<L, R> {

		private final Either<L, R> either;

		LeftProjection(Either<L, R> either) {
			this.either = either;
		}

		public L get() {
			if (either.isLeft()) {
				return asLeft();
			} else {
				throw new NoSuchElementException("Either.left().get() on Right");
			}
		}

		@Override
		public L orElse(L other) {
			return either.isLeft() ? asLeft() : other;
		}

		@Override
		public L orElseGet(Function<? super R, ? extends L> other) {
			if (either.isLeft()) {
				return asLeft();
			} else {
				return other.apply(asRight());
			}
		}

		@Override
		public void orElseRun(Consumer<? super R> action) {
			if (either.isRight()) {
				action.accept(asRight());
			}
		}

		@Override
		public <X extends Throwable> L orElseThrow(Function<? super R, X> exceptionFunction) throws X {
			if (either.isLeft()) {
				return asLeft();
			} else {
				throw exceptionFunction.apply(asRight());
			}
		}

		@Override
		public Option<L> toOption() {
			if (either.isLeft()) {
				return new Some<>(asLeft());
			} else {
				return None.instance();
			}
		}

		@Override
		public Either<L, R> toEither() {
			return either;
		}

		public Option<Either<L, R>> filter(Predicate<? super L> predicate) {
			Objects.requireNonNull(predicate);
			if (either.isLeft() && predicate.test(asLeft())) {
				return new Some<>(either);
			} else {
				return None.instance();
			}
		}

		public void forEach(Consumer<? super L> action) {
			Objects.requireNonNull(action);
			if (either.isLeft()) {
				action.accept(asLeft());
			}
		}

		@SuppressWarnings("unchecked")
		public <U> Either<U, R> map(Function<? super L, ? extends U> mapper) {
			Objects.requireNonNull(mapper);
			if (either.isLeft())
				return new Left<>(mapper.apply(asLeft()));
			else {
				return (Either<U,R>) either;
			}
		}

		@SuppressWarnings("unchecked")
		public <U> Either<U, R> flatMap(Function<? super L, ? extends Either<U, R>> mapper) {
			Objects.requireNonNull(mapper);
			if (either.isLeft()) {
				return mapper.apply(asLeft());
			} else {
				return (Either<U,R>) either;
			}
		}

		@Override
		public boolean equals(Object obj) {
			return (obj == this) || (obj instanceof LeftProjection && Objects.equals(either, ((LeftProjection<?, ?>) obj).either));
		}

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

		@Override
		public String toString() {
			return String.format("LeftProjection(%s)", either);
		}

		private L asLeft() {
			return ((Left<L, R>) either).left;
		}

		private R asRight() {
			return ((Right<L, R>) either).right;
		}
	}

    /**
     * A right projection of an either.
     *
     * @param <L> The type of the Left value of an Either.
     * @param <R> The type of the Right value of an Either.
     * @since 1.0.0
     */
{'fraction_non_alphanumeric': 0.14003015454202788, 'fraction_numerical': 0.00395778364116095, 'mean_word_length': 3.0616150019135095, 'pattern_counts': {'":': 0, '<': 105, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2548061', 'n_tokens_mistral': 3932, 'n_tokens_neox': 3442, 'n_words': 1078}