package haskell.prelude;

public class Operator<A, B, C>
        extends Function2<A, B, C> {

    protected Operator(final java.lang.String name) {
        super(name);
    }

    /**
     * public static C methodName(A x, B y);
     */
    public Operator(
            final java.lang.String name,
            final Class<?> clazz,
            final Class<?> returnType,
            final java.lang.String methodName) {
        super(name, clazz, returnType, methodName, 2);
    }

    /**
     * public C methodName(A x, B y);
     */
    public Operator(
            final java.lang.String name,
            final Object target,
            final Class<?> returnType,
            final java.lang.String methodName) {
        super(name, target, returnType, methodName, 2);
    }

    /**
     * public static C methodName(A x, B y);
     */
    public Operator(
            final java.lang.String name,
            final Class<?> clazz,
            final Class<?> returnType,
            final java.lang.String methodName,
            final Class<A> typeA,
            final Class<B> typeB) {
        super(name, clazz, returnType, methodName, typeA, typeB);
    }

    /**
     * public C methodName(A x, B y);
     */
    public Operator(
            final java.lang.String name,
            final Object target,
            final Class<?> returnType,
            final java.lang.String methodName,
            final Class<A> typeA,
            final Class<B> typeB) {
        super(name, target, returnType, methodName, typeA, typeB);
    }

    /**
     * (op x)
     */
    public Function<A, C> apply2(final B x) {
        return new Function<A, C>(toString((A) null, x)) {
            @Override
            public C apply(final A y) {
                return apply(y, x);
            }
        };
    }

    /**
     * (op)
     */
    @Override
    public java.lang.String toString() {
        return '(' + $name() + ')';
    }

    /**
     * (x op y)
     */
    @Override
    public java.lang.String toString(final Object... xs) {
        if (xs.length == 1) {
            return expression(xs[0], $name());
        } else if (xs[0] == null) {
            return expression($name(), xs[1]);
        } else {
            return expression(xs[0], $name(), xs[1]);
        }
    }

    /**
     * (x op)
     */
    public static java.lang.String expression(
            final Object x, final java.lang.String op) {
        return "(" + x + " " + op + ")";
    }

    /**
     * (x op y)
     */
    public static java.lang.String expression(
            final Object x, final java.lang.String op, final Object y) {
        return "(" + x + " " + op + " " + y + ")";
    }

}
