fj.Equal Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of functionaljava Show documentation
Show all versions of functionaljava Show documentation
Functional Java is an open source library that supports closures for the Java programming language
package fj;
import fj.data.Array;
import fj.data.Either;
import fj.data.LazyString;
import fj.data.List;
import fj.data.Natural;
import fj.data.NonEmptyList;
import fj.data.Option;
import fj.data.Seq;
import fj.data.Set;
import fj.data.Stream;
import fj.data.Tree;
import fj.data.TreeMap;
import fj.data.Validation;
import fj.data.Writer;
import fj.data.hamt.BitSet;
import fj.data.hlist.HList;
import fj.data.vector.V2;
import fj.data.vector.V3;
import fj.data.vector.V4;
import fj.data.vector.V5;
import fj.data.vector.V6;
import fj.data.vector.V7;
import fj.data.vector.V8;
import java.math.BigDecimal;
import java.math.BigInteger;
import static fj.Function.compose;
import static fj.Function.constant;
import static fj.Function.curry;
/**
* Tests for equality between two objects.
*
* @version %build.number%
*/
public final class Equal {
/**
* Primitives functions of Equal: minimal definition and overridable methods.
*/
public interface Definition {
F equal(A a);
default boolean equal(A a1, A a2) {
return equal(a1).f(a2);
}
}
/**
* Primitives functions of Equal: alternative minimal definition and overridable methods.
*/
public interface AltDefinition extends Definition {
@Override
boolean equal(A a1, A a2);
@Override
default F equal(A a) {
return a2 -> equal(a, a2);
}
}
private final Definition def;
private Equal(final Definition def) {
this.def = def;
}
/**
* Returns true
if the two given arguments are equal, false
otherwise.
*
* @param a1 An object to test for equality against another.
* @param a2 An object to test for equality against another.
* @return true
if the two given arguments are equal, false
otherwise.
*/
public boolean eq(final A a1, final A a2) {
return def.equal(a1, a2);
}
/**
* Returns true
if the two given arguments are not equal, false
otherwise.
*
* @param a1 An object to test for inequality against another.
* @param a2 An object to test for inequality against another.
* @return true
if the two given arguments are not equal, false
otherwise.
*/
public boolean notEq(final A a1, final A a2) {
return !def.equal(a1, a2);
}
/**
* First-class equality check.
*
* @return A function that returns true
if the two given arguments are equal.
*/
public F2 eq() {
return def::equal;
}
/**
* Partially applied equality check.
*
* @param a An object to test for equality against another.
* @return A function that returns true
if the given argument equals the argument to this method.
*/
public F eq(final A a) {
return def.equal(a);
}
/**
* Maps the given function across this equal as a contra-variant functor.
*
* @param f The function to map.
* @return A new equal.
*/
public Equal contramap(final F f) {
Definition eaDef = def;
return equalDef(new Definition(){
@Override
public F equal(B b) {
return compose(eaDef.equal(f.f(b)), f);
}
@Override
public boolean equal(B b1, B b2) {
return eaDef.equal(f.f(b1), f.f(b2));
}
});
}
/**
* Constructs an equal instance from the given function.
*
* Java 8+ users: use {@link #equalDef(Definition)} instead.
*
* @param f The function to construct the equal with.
* @return An equal instance from the given function.
*/
public static Equal equal(final F> f) {
return new Equal<>(f::f);
}
/**
* Constructs an equal instance from the given function.
*
* Java 8+ users: use {@link #equalDef(AltDefinition)} instead.
*
* @param f The function to construct the equal with.
* @return An equal instance from the given function.
*/
public static Equal equal(final F2 f) {
return equalDef(f::f);
}
/**
* Constructs an equal instance from the given definition.
*
* @param definition a definition of the equal instance.
* @return An equal instance from the given function.
*/
public static Equal equalDef(final Definition definition) {
return new Equal<>(definition);
}
/**
* Constructs an equal instance from the given (alternative) definition.
*
* @param definition a definition of the equal instance.
* @return An equal instance from the given function.
*/
public static Equal equalDef(final AltDefinition definition) {
return new Equal<>(definition);
}
/**
* Returns an equal instance that uses the {@link Object#equals(Object)} method to test for
* equality.
*
* @return An equal instance that uses the {@link Object#equals(Object)} method to test for
* equality.
*/
public static Equal anyEqual() {
return equalDef(new Definition() {
@Override
public F equal(A a) {
return a::equals;
}
@Override
public boolean equal(A a1, A a2) {
return a1.equals(a2);
}
});
}
/**
* An equal instance for the boolean
type.
*/
public static final Equal booleanEqual = anyEqual();
/**
* An equal instance for the byte
type.
*/
public static final Equal byteEqual = anyEqual();
/**
* An equal instance for the char
type.
*/
public static final Equal charEqual = anyEqual();
/**
* An equal instance for the double
type.
*/
public static final Equal doubleEqual = anyEqual();
/**
* An equal instance for the float
type.
*/
public static final Equal floatEqual = anyEqual();
/**
* An equal instance for the int
type.
*/
public static final Equal intEqual = anyEqual();
/**
* An equal instance for the BigInteger
type.
*/
public static final Equal bigintEqual = anyEqual();
/**
* An equal instance for the BigDecimal
type.
*/
public static final Equal bigdecimalEqual = anyEqual();
/**
* An equal instance for the long
type.
*/
public static final Equal longEqual = anyEqual();
/**
* An equal instance for the short
type.
*/
public static final Equal shortEqual = anyEqual();
/**
* An equal instance for the Natural
type.
*/
public static final Equal naturalEqual = bigintEqual.contramap(Natural::bigIntegerValue);
/**
* An equal instance for the {@link String} type.
*/
public static final Equal stringEqual = anyEqual();
/**
* An equal instance for the {@link StringBuffer} type.
*/
public static final Equal stringBufferEqual =
equalDef((sb1, sb2) -> {
if (sb1.length() == sb2.length()) {
for (int i = 0; i < sb1.length(); i++)
if (sb1.charAt(i) != sb2.charAt(i))
return false;
return true;
} else
return false;
});
/**
* An equal instance for the {@link StringBuilder} type.
*/
public static final Equal stringBuilderEqual =
equalDef((sb1, sb2) -> {
if (sb1.length() == sb2.length()) {
for (int i = 0; i < sb1.length(); i++)
if (sb1.charAt(i) != sb2.charAt(i))
return false;
return true;
} else
return false;
});
/**
* An equal instance for the {@link BitSet} type.
*/
public static final Equal bitSetSequal = equalDef((bs1, bs2) -> bs1.longValue() == bs2.longValue());
/**
* An equal instance for the {@link Either} type.
*
* @param ea Equality across the left side of {@link Either}.
* @param eb Equality across the right side of {@link Either}.
* @return An equal instance for the {@link Either} type.
*/
public static Equal> eitherEqual(final Equal ea, final Equal eb) {
Definition eaDef = ea.def;
Definition ebDef = eb.def;
return equalDef(e1 -> e1.either(
a1 -> Either.either_(eaDef.equal(a1), (B __) -> false),
b1 -> Either.either_((A __)-> false, ebDef.equal(b1))
));
}
/**
* An equal instance for the {@link Validation} type.
*
* @param ea Equality across the failing side of {@link Validation}.
* @param eb Equality across the succeeding side of {@link Validation}.
* @return An equal instance for the {@link Validation} type.
*/
public static Equal> validationEqual(final Equal ea, final Equal eb) {
return eitherEqual(ea, eb).contramap(Validation.either());
}
/**
* An equal instance for the {@link List} type.
*
* @param ea Equality across the elements of the list.
* @return An equal instance for the {@link List} type.
*/
public static Equal> listEqual(final Equal ea) {
Definition eaDef = ea.def;
return equalDef((a1, a2) -> {
List x1 = a1;
List x2 = a2;
while (x1.isNotEmpty() && x2.isNotEmpty()) {
if (!eaDef.equal(x1.head(), x2.head()))
return false;
x1 = x1.tail();
x2 = x2.tail();
}
return x1.isEmpty() && x2.isEmpty();
});
}
/**
* An equal instance for the {@link NonEmptyList} type.
*
* @param ea Equality across the elements of the non-empty list.
* @return An equal instance for the {@link NonEmptyList} type.
*/
public static Equal> nonEmptyListEqual(final Equal ea) {
return listEqual(ea).contramap(NonEmptyList.toList_());
}
/**
* An equal instance for the {@link Option} type.
*
* @param ea Equality across the element of the option.
* @return An equal instance for the {@link Option} type.
*/
public static Equal