docs: public static String print(DataType dataType) {
          final StringBuilder builder = new StringBuilder();
          for(Annotation annotation : dataType.annotations) {
              builder.append(print(annotation));
              builder.append("\n");
          }
          builder.append(dataType.name);
          dataType.extendedType._switch(new Optional.SwitchBlock<RefType>() {
              @Override
              public void _case(Some<RefType> x) {
                  builder.append(" extends ");
                  builder.append(print(x.value));
              }
  
              @Override
              public void _case(None<RefType> x) {
              }
          });
          if (!dataType.implementedTypes.isEmpty()) {
              builder.append(" implements ");
              boolean first = true;
              for (RefType type : dataType.implementedTypes) {
                  if (first) {
                      first = false;
                  } else {
                      builder.append(", ");
                  }
                  builder.append(print(type));
              }
          }
          builder.append(" =\n    ");
          boolean first = true;
          for (Constructor constructor : dataType.constructors) {
              if (first) {
                  first = false;
              } else {
                  builder.append("\n  | ");
              }
              builder.append(print(constructor));
          }
          return builder.toString();
      }