===========================
Type variables
===========================

type 'a t = 'a
type '\#if \#then = '\#else
type ('a, 'b) t = 'a
type +'a t = 'a
type !+'a t = 'a
type +!'a t = 'a

---

(compilation_unit
  (type_definition
    (type_binding
      (type_variable)
      name: (type_constructor)
      equation: (type_variable)))
  (type_definition
    (type_binding
      (type_variable)
      name: (type_constructor)
      equation: (type_variable)))
  (type_definition
    (type_binding
      (type_variable)
      (type_variable)
      name: (type_constructor)
      equation: (type_variable)))
  (type_definition
    (type_binding
      (type_variable)
      name: (type_constructor)
      equation: (type_variable)))
  (type_definition
    (type_binding
      (type_variable)
      name: (type_constructor)
      equation: (type_variable)))
  (type_definition
    (type_binding
      (type_variable)
      name: (type_constructor)
      equation: (type_variable))))

===========================
Type constructors
===========================

type t = t
type \#begin = \#end
type t = M.t
type \#try = M.\#with
type t = M(M).t

---

(compilation_unit
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (type_constructor_path
        (type_constructor))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (type_constructor_path
        (type_constructor))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (type_constructor_path
        (extended_module_path
          (module_name))
        (type_constructor))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (type_constructor_path
        (extended_module_path
          (module_name))
        (type_constructor))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (type_constructor_path
        (extended_module_path
          (extended_module_path
            (module_name))
          (extended_module_path
            (module_name)))
        (type_constructor)))))

===========================
Constructed types
===========================

type t = int list
type t = int list list

---

(compilation_unit
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (constructed_type
        (type_constructor_path
          (type_constructor))
        (type_constructor_path
          (type_constructor)))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (constructed_type
        (constructed_type
          (type_constructor_path
            (type_constructor))
          (type_constructor_path
            (type_constructor)))
        (type_constructor_path
          (type_constructor))))))

===========================
Polymorphic variant types
===========================

type t = [`A | `B of t]
type t = [>
  | t
  | `C
]
type t = [< `A of t & t ]
type t = [< `A > `A ]
type t = M.[`A]

---

(compilation_unit
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (polymorphic_variant_type
        (tag_specification
          (tag))
        (tag_specification
          (tag)
          (type_constructor_path
            (type_constructor))))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (polymorphic_variant_type
        (type_constructor_path
          (type_constructor))
        (tag_specification
          (tag)))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (polymorphic_variant_type
        (tag_specification
          (tag)
          (type_constructor_path
            (type_constructor))
          (type_constructor_path
            (type_constructor))))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (polymorphic_variant_type
        (tag_specification
          (tag))
        (tag))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (local_open_type
        (extended_module_path
          (module_name))
        type: (polymorphic_variant_type
          (tag_specification
            (tag)))))))

===========================
Package types
===========================

type t = (module T)
type t = M.(module T)

---

(compilation_unit
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (package_type
        (module_type_path
          (module_type_name)))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (local_open_type
        (extended_module_path
          (module_name))
        type: (package_type
          (module_type_path
            (module_type_name)))))))

===========================
Function types
===========================

type t = t -> t
type t = t -> t -> t
type t = l:t -> ?l:t -> t

---

(compilation_unit
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (function_type
        domain: (type_constructor_path
          (type_constructor))
        codomain: (type_constructor_path
          (type_constructor)))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (function_type
        domain: (type_constructor_path
          (type_constructor))
        codomain: (function_type
          domain: (type_constructor_path
            (type_constructor))
          codomain: (type_constructor_path
            (type_constructor))))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (function_type
        domain: (labeled_argument_type
          (label_name)
          type: (type_constructor_path
            (type_constructor)))
        codomain: (function_type
          domain: (labeled_argument_type
            (label_name)
            type: (type_constructor_path
              (type_constructor)))
          codomain: (type_constructor_path
            (type_constructor)))))))

===========================
Tuple types
===========================

type t = t * t
type t = t * t * t
type t = a:t * b:t * t

---

(compilation_unit
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (tuple_type
        (type_constructor_path
          (type_constructor))
        (type_constructor_path
          (type_constructor)))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (tuple_type
        (type_constructor_path
          (type_constructor))
        (type_constructor_path
          (type_constructor))
        (type_constructor_path
          (type_constructor)))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (tuple_type
        (labeled_tuple_element_type
          (label_name)
          type: (type_constructor_path
            (type_constructor)))
        (labeled_tuple_element_type
          (label_name)
          type: (type_constructor_path
            (type_constructor)))
        (type_constructor_path
          (type_constructor))))))

===========================
Aliased types
===========================

type t = t as 't

---

(compilation_unit
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (aliased_type
        type: (type_constructor_path
          (type_constructor))
        alias: (type_variable)))))

===========================
Parenthesized types
===========================

type t = (t)
type t = M.(t)

---

(compilation_unit
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (parenthesized_type
        (type_constructor_path
          (type_constructor)))))
  (type_definition
    (type_binding
      name: (type_constructor)
      equation: (local_open_type
        (extended_module_path
          (module_name))
        type: (type_constructor_path
          (type_constructor))))))
