@Override
    protected String printType(@NotNull CyclicTypeRecorder ctr) {
        StringBuilder sb = new StringBuilder();

        Integer num = ctr.visit(this);
        if (num != null) {
            sb.append("#").append(num);
        } else {
            int newNum = ctr.push(this);
            boolean first = true;
            sb.append("{");

            for (Type t : types) {
                if (!first) {
                    sb.append(" | ");
                }
                sb.append(t.printType(ctr));
                first = false;
            }

            if (ctr.isUsed(this)) {
                sb.append("=#").append(newNum).append(":");
            }

            sb.append("}");
            ctr.pop(this);
        }

        return sb.toString();
    }