package fj;
import static fj.Function.curry;
import fj.data.hlist.HList;
import fj.data.Array;
import fj.data.Either;
import fj.data.LazyString;
import fj.data.List;
import fj.data.NonEmptyList;
import fj.data.Option;
import fj.data.Set;
import fj.data.Stream;
import fj.data.Tree;
import fj.data.Validation;
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.BigInteger;
import java.math.BigDecimal;
/**
* Tests for equality between two objects.
*
* @version %build.number%
*/
public final class Equal {
private final F> f;
private Equal(final F> f) {
this.f = f;
}
/**
* 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 f.f(a1).f(a2);
}
/**
* First-class equality check.
*
* @return A function that returns true if the two given arguments are equal.
*/
public F2 eq() {
return new F2() {
public Boolean f(final A a, final A a1) {
return eq(a, a1);
}
};
}
/**
* 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 new F() {
public Boolean f(final A a1) {
return eq(a, a1);
}
};
}
/**
* Maps the given function across this equal as a contra-variant functor.
*
* @param f The function to map.
* @return A new equal.
*/
public Equal comap(final F f) {
return equal(f.andThen().o(this.f).o(f));
}
/**
* Constructs an equal instance from the given function.
*
* @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);
}
/**
* 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 new Equal(new F>() {
public F f(final A a1) {
return new F() {
public Boolean f(final 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 {@link String} type.
*/
public static final Equal stringEqual = anyEqual();
/**
* An equal instance for the {@link StringBuffer} type.
*/
public static final Equal stringBufferEqual =
new Equal(new F>() {
public F f(final StringBuffer sb1) {
return new F() {
public Boolean f(final StringBuffer 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 =
new Equal(new F>() {
public F f(final StringBuilder sb1) {
return new F() {
public Boolean f(final StringBuilder 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 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) {
return new Equal>(new F, F, Boolean>>() {
public F, Boolean> f(final Either e1) {
return new F, Boolean>() {
public Boolean f(final Either e2) {
return e1.isLeft() && e2.isLeft() && ea.f.f(e1.left().value()).f(e2.left().value()) ||
e1.isRight() && e2.isRight() && eb.f.f(e1.right().value()).f(e2.right().value());
}
};
}
});
}
/**
* 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).comap(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) {
return new Equal>(new F, F, Boolean>>() {
public F, Boolean> f(final List a1) {
return new F, Boolean>() {
public Boolean f(final List a2) {
List x1 = a1;
List x2 = a2;
while (x1.isNotEmpty() && x2.isNotEmpty()) {
if (!ea.eq(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).comap(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