package haskell.prelude;

import haskell.lang.Class;

/**
 * class Eq a
 */
public interface Eq<A extends Eq<A>>
        extends Class<A> {

    /**
     * this == x
     */
    Bool _eq_(A x);

    /**
     * this /= x
     */
    Bool _ne_(A x);

    abstract class Support<A extends Eq<A>> {

        protected final java.lang.Class<A> a;

        protected Support(final java.lang.Class<A> a) {
            this.a = a;
        }

        // Minimal complete definition:
        //     (==) or (/=)

        /**
         * (==) :: a -> a -> Bool
         */
        public final Operator<A, A, Bool> eq() {
            return new Operator<A, A, Bool>("==", this, Bool.class, "eq");
        }

        /**
         * x == y = not (x /= y)
         */
        public Bool eq(final A x, final A y) {
            return Bool.not(ne(x, y));
        }

        /**
         * (/=) :: a -> a -> Bool
         */
        public final Operator<A, A, Bool> ne() {
            return new Operator<A, A, Bool>("/=", this, Bool.class, "ne");
        }

        /**
         * x /= y = not (x == y)
         */
        public Bool ne(final A x, final A y) {
            return Bool.not(eq(x, y));
        }

    }

}
