<commit_before>/**
 * The tags for each kind of Type defined here.
 */
export const enum TypeKind {
  PRIMITIVE,
  ANY,
  VOID,
  FUN,
  VARIADIC_FUN,
  CODE,
  CONSTRUCTOR,
  INSTANCE,
  QUANTIFIED,
  VARIABLE,
  OVERLOADED,
  TUPLE,
}

/**
 * The base type for all types.
 */
interface BaseType {
  type: TypeKind;
}

/**
 * Primitive types. Each primitive type is a (shared) instance of this class.
 */
export class PrimitiveType implements BaseType {
  public type: TypeKind.PRIMITIVE;
  constructor(public name: string) { }
}
PrimitiveType.prototype.type = TypeKind.PRIMITIVE;

/**
 * A "top" type: a supertype of everything.
 */
export class AnyType implements BaseType {
  public type: TypeKind.ANY;
}
AnyType.prototype.type = TypeKind.ANY;
export const ANY = new AnyType();

/**
 * A "bottom" type: a subtype of everything.
 */
export class VoidType implements BaseType {
  public type: TypeKind.VOID;
}
VoidType.prototype.type = TypeKind.VOID;
export const VOID = new VoidType();

abstract class BaseFunType {
  constructor(
    /**
     * The parameter types.
     */
    public params: Type[],

    /**
     * The return type.
     */
    public ret: Type
  ) {}
}

/**
 * Function types.
 */
export class FunType extends BaseFunType implements BaseType {
  public type: TypeKind.FUN;
}
FunType.prototype.type = TypeKind.FUN;

/**
 * Variadic function types. These functions can take any number of arguments
 * of a single type: the `params` array must have length 1.
 */
export class VariadicFunType extends BaseFunType implements BaseType {
  public type: TypeKind.VARIADIC_FUN;
}
VariadicFunType.prototype.type = TypeKind.VARIADIC_FUN;


/**
 * Code types.
 */
export class CodeType implements BaseType {
  public type: TypeKind.CODE;
  constructor(
    public inner: Type,
    public annotation: string,
    public snippet: number | null = null,  // Corresponding escape ID.
    public snippet_var: TypeVariable | null = null  // Snippet polymorphism.
  ) {}
}
CodeType.prototype.type = TypeKind.CODE;

// Type constructors: the basic element of parametricity.
export class ConstructorType implements BaseType {
  public type: TypeKind.CONSTRUCTOR;
  constructor(public name: string) { }
  instance(arg: Type) {
    return new InstanceType(this, arg);
  }
}
ConstructorType.prototype.type = TypeKind.CONSTRUCTOR;

export class InstanceType implements BaseType {
  public type: TypeKind.INSTANCE;
  constructor(public cons: ConstructorType, public arg: Type) { }
}
InstanceType.prototype.type = TypeKind.INSTANCE;

// Slightly more general parametricity with a universal quantifier.
export class QuantifiedType implements BaseType {
  public type: TypeKind.QUANTIFIED;
  constructor(public variable: TypeVariable, public inner: Type) { }
}
QuantifiedType.prototype.type = TypeKind.QUANTIFIED;

export class VariableType implements BaseType {
  public type: TypeKind.VARIABLE;
  constructor(public variable: TypeVariable) { }
}
VariableType.prototype.type = TypeKind.VARIABLE;

// Simple overloading.
export class OverloadedType implements BaseType {
  public type: TypeKind.OVERLOADED;
  constructor(public types: Type[]) { }
}
OverloadedType.prototype.type = TypeKind.OVERLOADED;

// Tuple (product) types.
export class TupleType implements BaseType {
  public type: TypeKind.TUPLE;
  constructor(public components: Type[]) { }
}
TupleType.prototype.type = TypeKind.TUPLE;

export type Type = PrimitiveType | AnyType | VoidType | FunType |<commit_msg>A few more comments<commit_after>/**
 * The tags for each kind of Type defined here.
 */
export const enum TypeKind {
  PRIMITIVE,
  ANY,
  VOID,
  FUN,
  VARIADIC_FUN,
  CODE,
  CONSTRUCTOR,
  INSTANCE,
  QUANTIFIED,
  VARIABLE,
  OVERLOADED,
  TUPLE,
}

/**
 * The base type for all types.
 */
interface BaseType {
  type: TypeKind;
}

/**
 * Primitive types. Each primitive type is a (shared) instance of this class.
 */
export class PrimitiveType implements BaseType {
  public type: TypeKind.PRIMITIVE;
  constructor(public name: string) { }
}
PrimitiveType.prototype.type = TypeKind.PRIMITIVE;

/**
 * A "top" type: a supertype of everything.
 */
export class AnyType implements BaseType {
  public type: TypeKind.ANY;
}
AnyType.prototype.type = TypeKind.ANY;
export const ANY = new AnyType();

/**
 * A "bottom" type: a subtype of everything.
 */
export class VoidType implements BaseType {
  public type: TypeKind.VOID;
}
VoidType.prototype.type = TypeKind.VOID;
export const VOID = new VoidType();

abstract class BaseFunType {
  constructor(
    /**
     * The parameter types.
     */
    public params: Type[],

    /**
     * The return type.
     */
    public ret: Type
  ) {}
}

/**
 * Function types.
 */
export class FunType extends BaseFunType implements BaseType {
  public type: TypeKind.FUN;
}
FunType.prototype.type = TypeKind.FUN;

/**
 * Variadic function types. These functions can take any number of arguments
 * of a single type: the `params` array must have length 1.
 */
export class VariadicFunType extends BaseFunType implements BaseType {
  public type: TypeKind.VARIADIC_FUN;
}
VariadicFunType.prototype.type = TypeKind.VARIADIC_FUN;


/**
 * Code types.
 */
export class CodeType implements BaseType {
  public type: TypeKind.CODE;
  constructor(
    public inner: Type,
    public annotation: string,
    public snippet: number | null = null,  // Corresponding escape ID.
    public snippet_var: TypeVariable | null = null  // Snippet polymorphism.
  ) {}
}
CodeType.prototype.type = TypeKind.CODE;

/**
 * Type constructors: the basic element of parametricity.
 */
export class ConstructorType implements BaseType {
  public type: TypeKind.CONSTRUCTOR;
  constructor(public name: string) { }
  instance(arg: Type) {
    return new InstanceType(this, arg);
  }
}
ConstructorType.prototype.type = TypeKind.CONSTRUCTOR;

export class InstanceType implements BaseType {
  public type: TypeKind.INSTANCE;
  constructor(public cons: ConstructorType, public arg: Type) { }
}
InstanceType.prototype.type = TypeKind.INSTANCE;

/**
 * Slightly more general parametricity with a universal quantifier.
 */
export class QuantifiedType implements BaseType {
  public type: TypeKind.QUANTIFIED;
  constructor(public variable: TypeVariable, public inner: Type) { }
}
QuantifiedType.prototype.type = TypeKind.QUANTIFIED;

export class VariableType implements BaseType {
  public type: TypeKind.VARIABLE;
  constructor(public variable: TypeVariable) { }
}
VariableType.prototype.type = TypeKind.VARIABLE;

/**
 * Simple overloading.
 */
export class OverloadedType implements BaseType {
  public type: TypeKind.OVERLOADED;
  constructor(public types: Type[]) { }
}
OverloadedType.prototype.type = TypeKind.OVERLOADED;

/**
 * Tuple (product) types.
 */
export class TupleType implements BaseType {
  public type: TypeKind.TUPLE;
  constructor(public components: Type[]) { }
}
TupleType.prototype.type = TypeKind.TUPLE;

/**
 * The type for all types.
 *
 * Using a union here, unlike using `BaseType` itself as the type for types,
 * lets us take advantage of TypeScript's "tagged union" functionality: for
 * example, the type checker can help us avoid non-exhaustive matches.
 */
export type Type = PrimitiveType | AnyType | VoidType | FunType |
{'fraction_non_alphanumeric': 0.09845132743362832, 'fraction_numerical': 0.0002765486725663717, 'mean_word_length': 3.9405737704918034, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1587747', 'n_tokens_mistral': 2216, 'n_tokens_neox': 2163, 'n_words': 681}