sig
  module M :
    functor (X : sig type 'a t end->
      sig
        module Tag_internal :
          sig
            type ('variant, 'args) create =
                Args of ('args -> 'variant)
              | Const of 'variant
            type ('variant, 'args) t = {
              label : string;
              rep : 'args X.t;
              arity : int;
              index : int;
              ocaml_repr : int;
              tyid : 'args Typename.t;
              create : ('variant, 'args) create;
            }
          end
        module Tag :
          sig
            type ('variant, 'args) create =
                Args of ('args -> 'variant)
              | Const of 'variant
            type ('variant, 'args) t
            val label : ('a, 'b) t -> string
            val arity : ('a, 'b) t -> int
            val index : ('a, 'b) t -> int
            val ocaml_repr : ('a, 'b) t -> int
            val create : ('variant, 'args) t -> ('variant, 'args) create
            val tyid : ('a, 'args) t -> 'args Typename.t
            val traverse : ('a, 'args) t -> 'args X.t
            val internal_use_only : ('a, 'b) Tag_internal.t -> ('a, 'b) t
          end
        module Variant_internal :
          sig
            type _ tag = Tag : ('variant, 'a) Tag.t -> 'variant tag
            type _ value =
                Value : ('variant, 'a) Tag.t * '-> 'variant value
            type 'a t = {
              typename : 'Typename.t;
              tags : 'a tag array;
              polymorphic : bool;
              value : '-> 'a value;
            }
          end
        module Variant :
          sig
            type _ tag = Tag : ('variant, 'args) Tag.t -> 'variant tag
            type _ value =
                Value : ('variant, 'args) Tag.t * 'args -> 'variant value
            type 'a t
            val typename_of_t : 'a t -> 'Typename.t
            val length : 'a t -> int
            val tag : 'a t -> int -> 'a tag
            val is_polymorphic : 'a t -> bool
            val value : 'a t -> '-> 'a value
            val fold :
              'a t -> init:'acc -> f:('acc -> 'a tag -> 'acc) -> 'acc
            val internal_use_only : 'Variant_internal.t -> 'a t
          end
        module Field_internal :
          sig
            type ('record, 'field) t = {
              label : string;
              rep : 'field X.t;
              index : int;
              tyid : 'field Typename.t;
              get : 'record -> 'field;
            }
          end
        module Field :
          sig
            type ('record, 'field) t
            val label : ('a, 'b) t -> string
            val index : ('a, 'b) t -> int
            val get : ('record, 'field) t -> 'record -> 'field
            val tyid : ('a, 'field) t -> 'field Typename.t
            val traverse : ('a, 'field) t -> 'field X.t
            val internal_use_only : ('a, 'b) Field_internal.t -> ('a, 'b) t
          end
        module Record_internal :
          sig
            type _ field = Field : ('record, 'a) Field.t -> 'record field
            type 'record fields = {
              get : 'field. ('record, 'field) Field.t -> 'field;
            }
            type 'a t = {
              typename : 'Typename.t;
              fields : 'a field array;
              has_double_array_tag : bool;
              create : 'a fields -> 'a;
            }
          end
        module Record :
          sig
            type _ field = Field : ('record, 'a) Field.t -> 'record field
            type 'record fields = {
              get : 'field. ('record, 'field) Field.t -> 'field;
            }
            type 'a t
            val typename_of_t : 'a t -> 'Typename.t
            val length : 'a t -> int
            val field : 'a t -> int -> 'a field
            val has_double_array_tag : 'a t -> bool
            val create : 'a t -> 'a fields -> 'a
            val fold :
              'a t -> init:'acc -> f:('acc -> 'a field -> 'acc) -> 'acc
            val internal_use_only : 'Record_internal.t -> 'a t
          end
      end
  module type S =
    sig
      type 'a t
      module Tag_internal :
        sig
          type ('variant, 'args) create =
              Args of ('args -> 'variant)
            | Const of 'variant
          type ('variant, 'args) t = {
            label : string;
            rep : 'args t;
            arity : int;
            index : int;
            ocaml_repr : int;
            tyid : 'args Typename.t;
            create : ('variant, 'args) create;
          }
        end
      module Tag :
        sig
          type ('variant, 'args) create =
              Args of ('args -> 'variant)
            | Const of 'variant
          type ('variant, 'args) t
          val label : ('a, 'b) t -> string
          val arity : ('a, 'b) t -> int
          val index : ('a, 'b) t -> int
          val ocaml_repr : ('a, 'b) t -> int
          val create : ('variant, 'args) t -> ('variant, 'args) create
          val tyid : ('a, 'args) t -> 'args Typename.t
          val traverse : ('a, 'args) t -> 'args t
          val internal_use_only : ('a, 'b) Tag_internal.t -> ('a, 'b) t
        end
      module Variant_internal :
        sig
          type _ tag = Tag : ('variant, 'a) Tag.t -> 'variant tag
          type _ value = Value : ('variant, 'a) Tag.t * '-> 'variant value
          type 'a t = {
            typename : 'Typename.t;
            tags : 'a tag array;
            polymorphic : bool;
            value : '-> 'a value;
          }
        end
      module Variant :
        sig
          type _ tag = Tag : ('variant, 'args) Tag.t -> 'variant tag
          type _ value =
              Value : ('variant, 'args) Tag.t * 'args -> 'variant value
          type 'a t
          val typename_of_t : 'a t -> 'Typename.t
          val length : 'a t -> int
          val tag : 'a t -> int -> 'a tag
          val is_polymorphic : 'a t -> bool
          val value : 'a t -> '-> 'a value
          val fold : 'a t -> init:'acc -> f:('acc -> 'a tag -> 'acc) -> 'acc
          val internal_use_only : 'Variant_internal.t -> 'a t
        end
      module Field_internal :
        sig
          type ('record, 'field) t = {
            label : string;
            rep : 'field t;
            index : int;
            tyid : 'field Typename.t;
            get : 'record -> 'field;
          }
        end
      module Field :
        sig
          type ('record, 'field) t
          val label : ('a, 'b) t -> string
          val index : ('a, 'b) t -> int
          val get : ('record, 'field) t -> 'record -> 'field
          val tyid : ('a, 'field) t -> 'field Typename.t
          val traverse : ('a, 'field) t -> 'field t
          val internal_use_only : ('a, 'b) Field_internal.t -> ('a, 'b) t
        end
      module Record_internal :
        sig
          type _ field = Field : ('record, 'a) Field.t -> 'record field
          type 'record fields = {
            get : 'field. ('record, 'field) Field.t -> 'field;
          }
          type 'a t = {
            typename : 'Typename.t;
            fields : 'a field array;
            has_double_array_tag : bool;
            create : 'a fields -> 'a;
          }
        end
      module Record :
        sig
          type _ field = Field : ('record, 'a) Field.t -> 'record field
          type 'record fields = {
            get : 'field. ('record, 'field) Field.t -> 'field;
          }
          type 'a t
          val typename_of_t : 'a t -> 'Typename.t
          val length : 'a t -> int
          val field : 'a t -> int -> 'a field
          val has_double_array_tag : 'a t -> bool
          val create : 'a t -> 'a fields -> 'a
          val fold :
            'a t -> init:'acc -> f:('acc -> 'a field -> 'acc) -> 'acc
          val internal_use_only : 'Record_internal.t -> 'a t
        end
    end
end