================================================================================
gadt: empty
================================================================================

data A where

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name))))

================================================================================
gadt: basic
================================================================================

data A a where
  A :: A -> !(A a) ->
    A a
  A :: {-# unpack #-} A -> A a

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name)
      (type_params
        (variable))
      (gadt_constructors
        (gadt_constructor
          (constructor)
          (prefix
            (function
              (name)
              (function
                (strict_field
                  (parens
                    (apply
                      (name)
                      (variable))))
                (apply
                  (name)
                  (variable))))))
        (gadt_constructor
          (constructor)
          (pragma)
          (prefix
            (function
              (name)
              (apply
                (name)
                (variable)))))))))

================================================================================
gadt: record
================================================================================

data A where
  A :: { a :: A, a :: !A } -> A

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name)
      (gadt_constructors
        (gadt_constructor
          (constructor)
          (record
            (fields
              (field
                (field_name
                  (variable))
                (name))
              (field
                (field_name
                  (variable))
                (strict_field
                  (name))))
            (name)))))))

================================================================================
gadt: signature
================================================================================

data A :: [*] -> * where

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name)
      (function
        (list
          (star))
        (star)))))

================================================================================
gadt: context
================================================================================

data A a => A where

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (context
        (apply
          (name)
          (variable)))
      (name))))

================================================================================
gadt: con context
================================================================================

data A where
  A :: A a => A

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name)
      (gadt_constructors
        (gadt_constructor
          (constructor)
          (context
            (apply
              (name)
              (variable)))
          (prefix
            (name)))))))

================================================================================
gadt: forall
================================================================================

data A where
  A :: ∀ a . A

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name)
      (gadt_constructors
        (gadt_constructor
          (constructor)
          (forall
            (quantified_variables
              (variable)))
          (prefix
            (name)))))))

================================================================================
gadt: simple deriving
================================================================================

data A where
  A :: A
  deriving A

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name)
      (gadt_constructors
        (gadt_constructor
          (constructor)
          (prefix
            (name))))
      (deriving
        (name)))))

================================================================================
gadt: deriving
================================================================================

data A where
  A :: A
  deriving stock A
  deriving A via (A A)

data A where
  A :: A deriving A deriving stock A

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name)
      (gadt_constructors
        (gadt_constructor
          (constructor)
          (prefix
            (name))))
      (deriving
        (deriving_strategy)
        (name))
      (deriving
        (name)
        (via
          (parens
            (apply
              (name)
              (name))))))
    (data_type
      (name)
      (gadt_constructors
        (gadt_constructor
          (constructor)
          (prefix
            (name))))
      (deriving
        (name))
      (deriving
        (deriving_strategy)
        (name)))))

================================================================================
gadt: symbolic operator
================================================================================

data a +++ b where
  (:+++) :: a -> b -> a +++ b

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (infix
        (variable)
        (operator)
        (variable))
      (gadt_constructors
        (gadt_constructor
          (prefix_id
            (constructor_operator))
          (prefix
            (function
              (variable)
              (function
                (variable)
                (infix
                  (variable)
                  (operator)
                  (variable))))))))))

================================================================================
gadt: newtype
================================================================================

newtype A where
  A :: A

--------------------------------------------------------------------------------

(haskell
  (declarations
    (newtype
      (name)
      (gadt_constructors
        (gadt_constructor
          (constructor)
          (prefix
            (name)))))))

================================================================================
gadt: symbolic type
================================================================================

data (:#) a where

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (prefix_id
        (constructor_operator))
      (type_params
        (variable)))))

================================================================================
gadt: strict/lazy
================================================================================

data A where
  A :: ~A -> A
  A :: !A -> A
  A :: A ~ A => A -> A

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name)
      (gadt_constructors
        (gadt_constructor
          (constructor)
          (prefix
            (function
              (lazy_field
                (name))
              (name))))
        (gadt_constructor
          (constructor)
          (prefix
            (function
              (strict_field
                (name))
              (name))))
        (gadt_constructor
          (constructor)
          (context
            (infix
              (name)
              (operator)
              (name)))
          (prefix
            (function
              (name)
              (name))))))))

================================================================================
gadt: type data
================================================================================

type data A a where
  A :: A ~ A => A a

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name)
      (type_params
        (variable))
      (gadt_constructors
        (gadt_constructor
          (constructor)
          (context
            (infix
              (name)
              (operator)
              (name)))
          (prefix
            (apply
              (name)
              (variable))))))))

================================================================================
gadt: multiplicity arrow
================================================================================

data A a where
  A :: a %1 -> A a

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name)
      (type_params
        (variable))
      (gadt_constructors
        (gadt_constructor
          (constructor)
          (prefix
            (linear_function
              (variable)
              (modifier
                (literal
                  (integer)))
              (apply
                (name)
                (variable)))))))))

================================================================================
gadt: con list
================================================================================

data A where
  A, A, A :: a -> A

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name)
      (gadt_constructors
        (gadt_constructor
          (binding_list
            (constructor)
            (constructor)
            (constructor))
          (prefix
            (function
              (variable)
              (name))))))))

================================================================================
gadt: record with context
================================================================================

data A where
  A :: ∀ a . A => { a :: A } -> A

--------------------------------------------------------------------------------

(haskell
  (declarations
    (data_type
      (name)
      (gadt_constructors
        (gadt_constructor
          (constructor)
          (forall
            (quantified_variables
              (variable)))
          (context
            (name))
          (record
            (fields
              (field
                (field_name
                  (variable))
                (name)))
            (name)))))))
