com.github.morinb.func.Either Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of func Show documentation
Show all versions of func Show documentation
Simple Functional interfaces for Java
/*
* Copyright 2024 Baptiste MORIN
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.morinb.func;
import java.io.Serializable;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Consumer;
/**
* An interface representing either a left or a right value.
*
* @param The type of the left value
* @param The type of the right value
*/
public sealed interface Either
extends Value, Serializable
permits Either.Left, Either.Right
{
/**
* Returns a new instance of Right with the specified value.
*
* @param the type of the left value
* @param the type of the right value
* @param value the value for the right side of the instance
* @return a new instance of Right with the specified value
*/
static Right right(final R value)
{
return new Right<>(value);
}
/**
* Returns a new instance of Left with the specified value.
*
* @param the type of the left value
* @param the type of the right value
* @param value the value for the left side of the instance
* @return a new instance of Left with the specified value
*/
static Left left(final L value)
{
return new Left<>(value);
}
/**
* Performs a no-operation and returns a new Either object with a Right value of null.
*
* @param The type of the Left value in the Either object.
* @param The type of the Right value in the Either object.
* @return A new Either object with a Right value of null.
*/
static Either noop()
{
return new Right<>(null);
}
/**
* Creates an empty Either object.
*
* @param The type of the left value.
* @param The type of the right value.
* @return An empty Either object of type Either<L, R>.
*/
static Either empty()
{
return new Left<>(null);
}
/**
* Zips or accumulates the values from multiple Either instances. If all input Either instances are Right,
* the transform function is applied to the values and the result is wrapped in a Right. If any of the input
* Either instances are Left, the Left values are accumulated into a NonEmptyList and returned.
*
* @param the type of the Left value
* @param the type of the Right value for Either a
* @param the type of the Right value for Either b
* @param the type of the result value
* @param a the Either for value a
* @param b the Either for value b
* @param transform the function to apply to the values if all Either instances are Right
* @return an Either containing the accumulated Left values or the result of applying the transform function
*/
static Either, Z> zipOrAccumulate(
final Either a,
final Either b,
final Function2 transform
)
{
return zipOrAccumulate(
a, b, Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb));
}
/**
* Zips or accumulates the values from multiple Either instances. If all input Either instances are Right,
* the transform function is applied to the values and the result is wrapped in a Right. If any of the input
* Either instances are Left, the Left values are accumulated into a NonEmptyList and returned.
*
* @param the type of the Left value
* @param the type of the Right value for Either a
* @param the type of the Right value for Either b
* @param the type of the Right value for Either c
* @param the type of the result value
* @param a the Either for value a
* @param b the Either for value b
* @param c the Either for value c
* @param transform the function to apply to the values if all Either instances are Right
* @return an Either containing the accumulated Left values or the result of applying the transform function
*/
static Either, Z> zipOrAccumulate(
final Either a,
final Either b,
final Either c,
final Function3 transform
)
{
return zipOrAccumulate(
a, b, c, Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb, cc));
}
/**
* Zips or accumulates the values from multiple Either instances. If all input Either instances are Right,
* the transform function is applied to the values and the result is wrapped in a Right. If any of the input
* Either instances are Left, the Left values are accumulated into a NonEmptyList and returned.
*
* @param the type of the Left value
* @param the type of the Right value for Either a
* @param the type of the Right value for Either b
* @param the type of the Right value for Either c
* @param the type of the Right value for Either d
* @param the type of the result value
* @param a the Either for value a
* @param b the Either for value b
* @param c the Either for value c
* @param d the Either for value d
* @param transform the function to apply to the values if all Either instances are Right
* @return an Either containing the accumulated Left values or the result of applying the transform function
*/
static Either, Z> zipOrAccumulate(
final Either a,
final Either b,
final Either c,
final Either d,
final Function4 transform
)
{
return zipOrAccumulate(
a, b, c, d, Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb, cc, dd));
}
/**
* Zips or accumulates the values from multiple Either instances. If all input Either instances are Right,
* the transform function is applied to the values and the result is wrapped in a Right. If any of the input
* Either instances are Left, the Left values are accumulated into a NonEmptyList and returned.
*
* @param the type of the Left value
* @param the type of the Right value for Either a
* @param the type of the Right value for Either b
* @param the type of the Right value for Either c
* @param the type of the Right value for Either d
* @param the type of the Right value for Either e
* @param the type of the result value
* @param a the Either for value a
* @param b the Either for value b
* @param c the Either for value c
* @param d the Either for value d
* @param e the Either for value e
* @param transform the function to apply to the values if all Either instances are Right
* @return an Either containing the accumulated Left values or the result of applying the transform function
*/
static Either, Z> zipOrAccumulate(
final Either a,
final Either b,
final Either c,
final Either d,
final Either e,
final Function5 transform
)
{
return zipOrAccumulate(
a, b, c, d, e, Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb, cc, dd, ee));
}
/**
* Zips or accumulates the values from multiple Either instances. If all input Either instances are Right,
* the transform function is applied to the values and the result is wrapped in a Right. If any of the input
* Either instances are Left, the Left values are accumulated into a NonEmptyList and returned.
*
* @param the type of the Left value
* @param the type of the Right value for Either a
* @param the type of the Right value for Either b
* @param the type of the Right value for Either c
* @param the type of the Right value for Either d
* @param the type of the Right value for Either e
* @param the type of the Right value for Either f
* @param the type of the result value
* @param a the Either for value a
* @param b the Either for value b
* @param c the Either for value c
* @param d the Either for value d
* @param e the Either for value e
* @param f the Either for value f
* @param transform the function to apply to the values if all Either instances are Right
* @return an Either containing the accumulated Left values or the result of applying the transform function
*/
static Either, Z> zipOrAccumulate(
final Either a,
final Either b,
final Either c,
final Either d,
final Either e,
final Either f,
final Function6 transform
)
{
return zipOrAccumulate(
a, b, c, d, e, f, Either.noop(), Either.noop(), Either.noop(), Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb, cc, dd, ee, ff));
}
/**
* Zips or accumulates the values from multiple Either instances. If all input Either instances are Right,
* the transform function is applied to the values and the result is wrapped in a Right. If any of the input
* Either instances are Left, the Left values are accumulated into a NonEmptyList and returned.
*
* @param the type of the Left value
* @param the type of the Right value for Either a
* @param the type of the Right value for Either b
* @param the type of the Right value for Either c
* @param the type of the Right value for Either d
* @param the type of the Right value for Either e
* @param the type of the Right value for Either f
* @param the type of the Right value for Either g
* @param the type of the result value
* @param a the Either for value a
* @param b the Either for value b
* @param c the Either for value c
* @param d the Either for value d
* @param e the Either for value e
* @param f the Either for value f
* @param g the Either for value g
* @param transform the function to apply to the values if all Either instances are Right
* @return an Either containing the accumulated Left values or the result of applying the transform function
*/
@SuppressWarnings("squid:S107")
static Either, Z> zipOrAccumulate(
final Either a,
final Either b,
final Either c,
final Either d,
final Either e,
final Either f,
final Either g,
final Function7 transform
)
{
return zipOrAccumulate(
a, b, c, d, e, f, g, Either.noop(), Either.noop(), Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb, cc, dd, ee, ff, gg));
}
/**
* Zips or accumulates the values from multiple Either instances. If all input Either instances are Right,
* the transform function is applied to the values and the result is wrapped in a Right. If any of the input
* Either instances are Left, the Left values are accumulated into a NonEmptyList and returned.
*
* @param the type of the Left value
* @param the type of the Right value for Either a
* @param the type of the Right value for Either b
* @param the type of the Right value for Either c
* @param the type of the Right value for Either d
* @param the type of the Right value for Either e
* @param the type of the Right value for Either f
* @param the type of the Right value for Either g
* @param the type of the Right value for Either h
* @param the type of the result value
* @param a the Either for value a
* @param b the Either for value b
* @param c the Either for value c
* @param d the Either for value d
* @param e the Either for value e
* @param f the Either for value f
* @param g the Either for value g
* @param h the Either for value h
* @param transform the function to apply to the values if all Either instances are Right
* @return an Either containing the accumulated Left values or the result of applying the transform function
*/
@SuppressWarnings("squid:S107")
static Either, Z> zipOrAccumulate(
final Either a,
final Either b,
final Either c,
final Either d,
final Either e,
final Either f,
final Either g,
final Either h,
final Function8 transform
)
{
return zipOrAccumulate(
a, b, c, d, e, f, g, h, Either.noop(), Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb, cc, dd, ee, ff, gg, hh));
}
/**
* Zips or accumulates the values from multiple Either instances. If all input Either instances are Right,
* the transform function is applied to the values and the result is wrapped in a Right. If any of the input
* Either instances are Left, the Left values are accumulated into a NonEmptyList and returned.
*
* @param the type of the Left value
* @param the type of the Right value for Either a
* @param the type of the Right value for Either b
* @param the type of the Right value for Either c
* @param the type of the Right value for Either d
* @param the type of the Right value for Either e
* @param the type of the Right value for Either f
* @param the type of the Right value for Either g
* @param the type of the Right value for Either h
* @param the type of the Right value for Either i
* @param the type of the result value
* @param a the Either for value a
* @param b the Either for value b
* @param c the Either for value c
* @param d the Either for value d
* @param e the Either for value e
* @param f the Either for value f
* @param g the Either for value g
* @param h the Either for value h
* @param i the Either for value i
* @param transform the function to apply to the values if all Either instances are Right
* @return an Either containing the accumulated Left values or the result of applying the transform function
*/
@SuppressWarnings("squid:S107")
static Either, Z> zipOrAccumulate(
final Either a,
final Either b,
final Either c,
final Either d,
final Either e,
final Either f,
final Either g,
final Either h,
final Either i,
final Function9 transform
)
{
return zipOrAccumulate(
a, b, c, d, e, f, g, h, i, Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb, cc, dd, ee, ff, gg, hh, ii));
}
/**
* Zips or accumulates the values from multiple Either instances. If all input Either instances are Right,
* the transform function is applied to the values and the result is wrapped in a Right. If any of the input
* Either instances are Left, the Left values are accumulated into a NonEmptyList and returned.
*
* @param the type of the Left value
* @param the type of the Right value for Either a
* @param the type of the Right value for Either b
* @param the type of the Right value for Either c
* @param the type of the Right value for Either d
* @param the type of the Right value for Either e
* @param the type of the Right value for Either f
* @param the type of the Right value for Either g
* @param the type of the Right value for Either h
* @param the type of the Right value for Either i
* @param the type of the Right value for Either j
* @param the type of the result value
* @param a the Either for value a
* @param b the Either for value b
* @param c the Either for value c
* @param d the Either for value d
* @param e the Either for value e
* @param f the Either for value f
* @param g the Either for value g
* @param h the Either for value h
* @param i the Either for value i
* @param j the Either for value j
* @param transform the function to apply to the values if all Either instances are Right
* @return an Either containing the accumulated Left values or the result of applying the transform function
*/
@SuppressWarnings({"squid:S107"})
static Either, Z> zipOrAccumulate(
final Either a,
final Either b,
final Either c,
final Either d,
final Either e,
final Either f,
final Either g,
final Either h,
final Either i,
final Either j,
final Function10 transform
)
{
final var eithers = FList.of(a, b, c, d, e, f, g, h, i, j);
final var errors = eithers
.filter(Either::isLeft)
.map(Either::getLeft);
if (errors.isEmpty())
{
return right(transform.apply(a.get(), b.get(), c.get(), d.get(), e.get(), f.get(), g.get(), h.get(), i.get(), j.get()));
}
else
{
return left(NonEmptyList.of(errors));
}
}
/**
* Combines or accumulates multiple Either into a single Either.
* If all the input Either are Right, then
* the transform function is applied to their Right values and the result is returned as a Right. If any of the
* input Either are Left, then the Left values are accumulated and returned as a NonEmptyList of errors.
*
* @param The type of the error value in the input Either and the resulting NonEmptyList of errors.
* @param The type of the Right value in the first input Either.
* @param The type of the Right value in the second input Either.
* @param The type of the result when transforming the Right values with the given transform function.
* @param a The first input Either.
* @param b The second input Either.
* @param transform The function to transform the Right values of the input Either into a result of type Z.
* @return Either - Either containing the accumulated errors as a NonEmptyList or the transformed right value as a Right.
*/
static Either, Z> zipOrAccumulateNel(
final Either, A> a,
final Either, B> b,
final Function2 transform
)
{
return zipOrAccumulateNel(
a, b, Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb));
}
/**
* Combines or accumulates multiple Either into a single Either.
* If all the input Either are Right, then
* the transform function is applied to their Right values and the result is returned as a Right. If any of the
* input Either are Left, then the Left values are accumulated and returned as a NonEmptyList of errors.
*
* @param The type of the error value in the input Either and the resulting NonEmptyList of errors.
* @param The type of the Right value in the first input Either.
* @param The type of the Right value in the second input Either.
* @param The type of the Right value in the third input Either.
* @param The type of the result when transforming the Right values with the given transform function.
* @param a The first input Either.
* @param b The second input Either.
* @param c The third input Either.
* @param transform The function to transform the Right values of the input Either into a result of type Z.
* @return Either - Either containing the accumulated errors as a NonEmptyList or the transformed right value as a Right.
*/
static Either, Z> zipOrAccumulateNel(
final Either, A> a,
final Either, B> b,
final Either, C> c,
final Function3 transform
)
{
return zipOrAccumulateNel(
a, b, c, Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb, cc));
}
/**
* Combines or accumulates multiple Either into a single Either.
* If all the input Either are Right, then
* the transform function is applied to their Right values and the result is returned as a Right. If any of the
* input Either are Left, then the Left values are accumulated and returned as a NonEmptyList of errors.
*
* @param The type of the error value in the input Either and the resulting NonEmptyList of errors.
* @param The type of the Right value in the first input Either.
* @param The type of the Right value in the second input Either.
* @param The type of the Right value in the third input Either.
* @param The type of the Right value in the fourth input Either.
* @param The type of the result when transforming the Right values with the given transform function.
* @param a The first input Either.
* @param b The second input Either.
* @param c The third input Either.
* @param d The fourth input Either.
* @param transform The function to transform the Right values of the input Either into a result of type Z.
* @return Either - Either containing the accumulated errors as a NonEmptyList or the transformed right value as a Right.
*/
static Either, Z> zipOrAccumulateNel(
final Either, A> a,
final Either, B> b,
final Either, C> c,
final Either, D> d,
final Function4 transform
)
{
return zipOrAccumulateNel(
a, b, c, d, Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb, cc, dd));
}
/**
* Combines or accumulates multiple Either into a single Either.
* If all the input Either are Right, then
* the transform function is applied to their Right values and the result is returned as a Right. If any of the
* input Either are Left, then the Left values are accumulated and returned as a NonEmptyList of errors.
*
* @param The type of the error value in the input Either and the resulting NonEmptyList of errors.
* @param The type of the Right value in the first input Either.
* @param The type of the Right value in the second input Either.
* @param The type of the Right value in the third input Either.
* @param The type of the Right value in the fourth input Either.
* @param The type of the Right value in the fifth input Either.
* @param The type of the result when transforming the Right values with the given transform function.
* @param a The first input Either.
* @param b The second input Either.
* @param c The third input Either.
* @param d The fourth input Either.
* @param e The fifth input Either.
* @param transform The function to transform the Right values of the input Either into a result of type Z.
* @return Either - Either containing the accumulated errors as a NonEmptyList or the transformed right value as a Right.
*/
static Either, Z> zipOrAccumulateNel(
final Either, A> a,
final Either, B> b,
final Either, C> c,
final Either, D> d,
final Either, E> e,
final Function5 transform
)
{
return zipOrAccumulateNel(
a, b, c, d, e, Either.noop(), Either.noop(), Either.noop(), Either.noop(), Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb, cc, dd, ee));
}
/**
* Combines or accumulates multiple Either into a single Either.
* If all the input Either are Right, then
* the transform function is applied to their Right values and the result is returned as a Right. If any of the
* input Either are Left, then the Left values are accumulated and returned as a NonEmptyList of errors.
*
* @param The type of the error value in the input Either and the resulting NonEmptyList of errors.
* @param The type of the Right value in the first input Either.
* @param The type of the Right value in the second input Either.
* @param The type of the Right value in the third input Either.
* @param The type of the Right value in the fourth input Either.
* @param The type of the Right value in the fifth input Either.
* @param The type of the Right value in the sixth input Either.
* @param The type of the result when transforming the Right values with the given transform function.
* @param a The first input Either.
* @param b The second input Either.
* @param c The third input Either.
* @param d The fourth input Either.
* @param e The fifth input Either.
* @param f The sixth input Either.
* @param transform The function to transform the Right values of the input Either into a result of type Z.
* @return Either - Either containing the accumulated errors as a NonEmptyList or the transformed right value as a Right.
*/
static Either, Z> zipOrAccumulateNel(
final Either, A> a,
final Either, B> b,
final Either, C> c,
final Either, D> d,
final Either, E> e,
final Either, F> f,
final Function6 transform
)
{
return zipOrAccumulateNel(
a, b, c, d, e, f, Either.noop(), Either.noop(), Either.noop(), Either.noop(),
(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj) -> transform.apply(aa, bb, cc, dd, ee, ff));
}
/**
* Combines or accumulates multiple Either into a single Either.
* If all the input Either are Right, then
* the transform function is applied to their Right values and the result is returned as a Right. If any of the
* input Either are Left, then the Left values are accumulated and returned as a NonEmptyList of errors.
*
* @param The type of the error value in the input Either and the resulting NonEmptyList of errors.
* @param The type of the Right value in the first input Either.
* @param The type of the Right value in the second input Either.
* @param The type of the Right value in the third input Either.
* @param The type of the Right value in the fourth input Either.
* @param The type of the Right value in the fifth input Either.
* @param The type of the Right value in the sixth input Either.
* @param The type of the Right value in the seventh input Either.
* @param The type of the result when transforming the Right values with the given transform function.
* @param a The first input Either.
* @param b The second input Either.
* @param c The third input Either.
* @param d The fourth input Either.
* @param e The fifth input Either.
* @param f The sixth input Either.
* @param g The seventh input Either.
* @param transform The function to transform the Right values of the input Either into a result of type Z.
* @return Either - Either containing the accumulated errors as a NonEmptyList or the transformed right value as a Right.
*/
@SuppressWarnings("squid:S107")
static Either, Z> zipOrAccumulateNel(
final Either, A> a,
final Either, B> b,
final Either