@Override
    public boolean equals(Object other) {
        if (typeStack.contains(this, other)) {
            return true;
        } else if (other instanceof TupleType) {
            List<Type> types1 = eltTypes;
            List<Type> types2 = ((TupleType) other).eltTypes;

            if (types1.size() == types2.size()) {
                typeStack.push(this, other);
                for (int i = 0; i < types1.size(); i++) {
                    if (!types1.get(i).equals(types2.get(i))) {
                        typeStack.pop(this, other);
                        return false;
                    }
                }
                typeStack.pop(this, other);
                return true;
            } else {
                return false;
            }

        } else {
            return false;
        }
    }