// Path: src/main/java/co/unruly/control/Piper.java
// public static <T> Piper<T> pipe(T element) {
//     return new Piper<T>(element);
// }
// 
// Path: src/main/java/co/unruly/control/result/Introducers.java
// @SuppressWarnings("unchecked")
// static <IS, OS extends IS> Function<IS, Result<OS, IS>> exactCastTo(Class<OS> targetClass) {
//     return input -> targetClass.equals(input.getClass())
//         ? Result.success((OS)input)
//         : Result.failure(input);
// }
// 
// Path: src/main/java/co/unruly/control/result/Resolvers.java
// static <OS, IS extends OS, FS extends OS, F> Function<Result<IS, F>, OS> ifFailed(Function<F, FS> recoveryFunction) {
//     return r -> r.either(identity(), recoveryFunction);
// }
// 
// Path: src/main/java/co/unruly/control/result/Transformers.java
// static <IS, OS, F> Function<Result<IS, F>, Result<OS, F>> onSuccess(Function<IS, OS> mappingFunction) {
//     return attempt(mappingFunction.andThen(Result::success));
// }


import java.util.function.BiPredicate;
import static co.unruly.control.Piper.pipe;
import static co.unruly.control.result.Introducers.exactCastTo;
import static co.unruly.control.result.Resolvers.ifFailed;
import static co.unruly.control.result.Transformers.onSuccess;
package co.unruly.control.casts;



public interface Equality {

    static <T> boolean areEqual(T self, Object other, BiPredicate<T, T> equalityChecker) {
        if(self==other) {
            return true;
        }

        if(other==null) {
            return false;
        }

        return pipe(other)
            .then(exactCastTo((Class<T>)self.getClass()))
// Path: src/main/java/co/unruly/control/Piper.java
// public static <T> Piper<T> pipe(T element) {
//     return new Piper<T>(element);
// }
// 
// Path: src/main/java/co/unruly/control/result/Introducers.java
// @SuppressWarnings("unchecked")
// static <IS, OS extends IS> Function<IS, Result<OS, IS>> exactCastTo(Class<OS> targetClass) {
//     return input -> targetClass.equals(input.getClass())
//         ? Result.success((OS)input)
//         : Result.failure(input);
// }
// 
// Path: src/main/java/co/unruly/control/result/Resolvers.java
// static <OS, IS extends OS, FS extends OS, F> Function<Result<IS, F>, OS> ifFailed(Function<F, FS> recoveryFunction) {
//     return r -> r.either(identity(), recoveryFunction);
// }
// 
// Path: src/main/java/co/unruly/control/result/Transformers.java
// static <IS, OS, F> Function<Result<IS, F>, Result<OS, F>> onSuccess(Function<IS, OS> mappingFunction) {
//     return attempt(mappingFunction.andThen(Result::success));
// }


// Path: src/main/java/co/unruly/control/casts/Equality.java
import java.util.function.BiPredicate;
import static co.unruly.control.Piper.pipe;
import static co.unruly.control.result.Introducers.exactCastTo;
import static co.unruly.control.result.Resolvers.ifFailed;
import static co.unruly.control.result.Transformers.onSuccess;

package co.unruly.control.casts;



public interface Equality {

    static <T> boolean areEqual(T self, Object other, BiPredicate<T, T> equalityChecker) {
        if(self==other) {
            return true;
        }

        if(other==null) {
            return false;
        }

        return pipe(other)
            .then(exactCastTo((Class<T>)self.getClass()))
            .then(onSuccess(o -> equalityChecker.test(self, o)))