================================================================================
pat: basic
================================================================================

a a (a:a : as) (a, a, (a, [a])) = a

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

(haskell
  declarations: (declarations
    (function
      name: (variable)
      patterns: (patterns
        (variable)
        (parens
          pattern: (infix
            left_operand: (variable)
            operator: (constructor_operator)
            right_operand: (infix
              left_operand: (variable)
              operator: (constructor_operator)
              right_operand: (variable))))
        (tuple
          element: (variable)
          element: (variable)
          element: (tuple
            element: (variable)
            element: (list
              element: (variable)))))
      match: (match
        expression: (variable)))))

================================================================================
pat: con simple
================================================================================

a A = a
a (A a) = a
a (A A A) = a
a (A a A (A a a A a)) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (constructor))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (parens
          (apply
            (constructor)
            (variable))))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (parens
          (apply
            (apply
              (constructor)
              (constructor))
            (constructor))))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (parens
          (apply
            (apply
              (apply
                (constructor)
                (variable))
              (constructor))
            (parens
              (apply
                (apply
                  (apply
                    (apply
                      (constructor)
                      (variable))
                    (variable))
                  (constructor))
                (variable))))))
      (match
        (variable)))))

================================================================================
pat: consym
================================================================================

a (a :++ a) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (infix
            (variable)
            (constructor_operator)
            (variable))))
      (match
        (variable)))))

================================================================================
pat: as
================================================================================

a a@(A a) a@(A a) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (as
          (variable)
          (parens
            (apply
              (constructor)
              (variable))))
        (as
          (variable)
          (parens
            (apply
              (constructor)
              (variable)))))
      (match
        (variable)))))

================================================================================
pat: wildcard
================================================================================

a (A _) _ a@_ a@(!_) a@(~_) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (apply
            (constructor)
            (wildcard)))
        (wildcard)
        (as
          (variable)
          (wildcard))
        (as
          (variable)
          (parens
            (strict
              (wildcard))))
        (as
          (variable)
          (parens
            (irrefutable
              (wildcard)))))
      (match
        (variable)))))

================================================================================
pat: literal
================================================================================

a 1 2 = 3
a "a" "a" = a
a 'a' 'b' = a
a 1.0 2.0 = 3.0

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (literal
          (integer))
        (literal
          (integer)))
      (match
        (literal
          (integer))))
    (function
      (variable)
      (patterns
        (literal
          (string))
        (literal
          (string)))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (literal
          (char))
        (literal
          (char)))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (literal
          (float))
        (literal
          (float)))
      (match
        (literal
          (float))))))

================================================================================
pat: record
================================================================================

f A {} = a
f A {..} = a
f a@A { a = a, b = a, a, .. } = a
f !A {} = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (record
          (constructor)))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (record
          (constructor)
          (field_pattern
            (wildcard))))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (as
          (variable)
          (record
            (constructor)
            (field_pattern
              (field_name
                (variable))
              (variable))
            (field_pattern
              (field_name
                (variable))
              (variable))
            (field_pattern
              (field_name
                (variable)))
            (field_pattern
              (wildcard)))))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (strict
          (record
            (constructor))))
      (match
        (variable)))))

================================================================================
pat: zero indent record
================================================================================

a =
  do
    A {
a = a
, a = a,
a, ..
} <- a
    a

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

(haskell
  (declarations
    (bind
      (variable)
      (match
        (do
          (bind
            (record
              (constructor)
              (field_pattern
                (field_name
                  (variable))
                (variable))
              (field_pattern
                (field_name
                  (variable))
                (variable))
              (field_pattern
                (field_name
                  (variable)))
              (field_pattern
                (wildcard)))
            (variable))
          (exp
            (variable)))))))

================================================================================
pat: strict
================================================================================

a !a = a
a !(!a) = a
a !(!(a, a), a) ![_] !_ = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (strict
          (variable)))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (strict
          (parens
            (strict
              (variable)))))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (strict
          (tuple
            (strict
              (tuple
                (variable)
                (variable)))
            (variable)))
        (strict
          (list
            (wildcard)))
        (strict
          (wildcard)))
      (match
        (variable)))))

================================================================================
pat: irrefutable
================================================================================

a ~a = a
a ~(~a) = a
a ~(~(a, a), a) ~[_] ~_ = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (irrefutable
          (variable)))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (irrefutable
          (parens
            (irrefutable
              (variable)))))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (irrefutable
          (tuple
            (irrefutable
              (tuple
                (variable)
                (variable)))
            (variable)))
        (irrefutable
          (list
            (wildcard)))
        (irrefutable
          (wildcard)))
      (match
        (variable)))))

================================================================================
pat: view pattern in argument patterns
================================================================================

a (a a -> Aa a a) = a
a (a -> a, a -> a) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (view_pattern
            (apply
              (variable)
              (variable))
            (apply
              (apply
                (constructor)
                (variable))
              (variable)))))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (tuple
          (view_pattern
            (variable)
            (variable))
          (view_pattern
            (variable)
            (variable))))
      (match
        (variable)))))

================================================================================
pat: view pattern in lambda
================================================================================

a = \ (a -> a) -> a

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

(haskell
  (declarations
    (bind
      (variable)
      (match
        (lambda
          (patterns
            (parens
              (view_pattern
                (variable)
                (variable))))
          (variable))))))

================================================================================
pat: parenthesized record
================================================================================

a (A{}) = a


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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (record
            (constructor))))
      (match
        (variable)))))

================================================================================
pat: guards
================================================================================

a a | a < 1, a > 1 = A
    | A (A A {..} _) : a <- a = A
    | otherwise = A

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

(haskell
  declarations: (declarations
    (function
      name: (variable)
      patterns: (patterns
        (variable))
      match: (match
        guards: (guards
          guard: (boolean
            (infix
              left_operand: (variable)
              operator: (operator)
              right_operand: (literal
                (integer))))
          guard: (boolean
            (infix
              left_operand: (variable)
              operator: (operator)
              right_operand: (literal
                (integer)))))
        expression: (constructor))
      match: (match
        guards: (guards
          guard: (pattern_guard
            pattern: (infix
              left_operand: (apply
                function: (constructor)
                argument: (parens
                  pattern: (apply
                    function: (apply
                      function: (constructor)
                      argument: (record
                        constructor: (constructor)
                        field: (field_pattern
                          (wildcard))))
                    argument: (wildcard))))
              operator: (constructor_operator)
              right_operand: (variable))
            expression: (variable)))
        expression: (constructor))
      match: (match
        guards: (guards
          guard: (boolean
            (variable)))
        expression: (constructor)))))

================================================================================
pat: view pattern in record
================================================================================

a A { a = a -> a } = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (record
          (constructor)
          (field_pattern
            (field_name
              (variable))
            (view_pattern
              (variable)
              (variable)))))
      (match
        (variable)))))

================================================================================
pat: unboxed tuple
================================================================================

a (# a, a, a #) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (unboxed_tuple
          (variable)
          (variable)
          (variable)))
      (match
        (variable)))))

================================================================================
pat: unboxed unit
================================================================================

a (# #) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (unboxed_unit))
      (match
        (variable)))))

================================================================================
pat: unboxed solo
================================================================================

a (# A a #) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (unboxed_tuple
          (apply
            (constructor)
            (variable))))
      (match
        (variable)))))

================================================================================
pat: unboxed sum, nullary tuple
================================================================================

a (# (# #) | | #) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (unboxed_sum
          (unboxed_unit)))
      (match
        (variable)))))

================================================================================
pat: signature
================================================================================

a (a :: A) = a
a = do
  let (a :: A, a) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (signature
            (variable)
            (name))))
      (match
        (variable)))
    (bind
      (variable)
      (match
        (do
          (let
            (local_binds
              (bind
                (tuple
                  (signature
                    (variable)
                    (name))
                  (variable))
                (match
                  (variable))))))))))

================================================================================
pat: do binder signature
================================================================================

a = do
  a :: A <- a

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

(haskell
  declarations: (declarations
    (bind
      name: (variable)
      match: (match
        expression: (do
          statement: (bind
            pattern: (signature
              pattern: (variable)
              type: (name))
            expression: (variable)))))))

================================================================================
pat: pattern binding signature
================================================================================

a :: A = a

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

(haskell
  (declarations
    (bind
      (signature
        (variable)
        (name))
      (match
        (variable)))))

================================================================================
pat: do binder view pattern
================================================================================

a = do
  (a -> a) <- a

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

(haskell
  (declarations
    (bind
      (variable)
      (match
        (do
          (bind
            (parens
              (view_pattern
                (variable)
                (variable)))
            (variable)))))))

================================================================================
pat: splice
================================================================================

a $(a) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (splice
          (parens
            (variable))))
      (match
        (variable)))))

================================================================================
pat: quasiqoute
================================================================================

a [a|a|] = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (quasiquote
          (quoter
            (variable))
          (quasiquote_body)))
      (match
        (variable)))))

================================================================================
pat: operator
================================================================================

a (++) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (prefix_id
          (operator)))
      (match
        (variable)))))

================================================================================
pat: negation
================================================================================

f (-1) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (negation
            (integer))))
      (match
        (variable)))))

================================================================================
pat: type binders
================================================================================

a @a (A @a @(a :: a) @(A a :: a) @(∀ a . A a :: a)) @[A a] = a

a = \ @a a @a -> a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (type_binder
          (variable))
        (parens
          (apply
            (apply
              (apply
                (apply
                  (constructor)
                  (type_binder
                    (variable)))
                (type_binder
                  (parens
                    (signature
                      (variable)
                      (variable)))))
              (type_binder
                (parens
                  (signature
                    (apply
                      (name)
                      (variable))
                    (variable)))))
            (type_binder
              (parens
                (signature
                  (forall
                    (quantified_variables
                      (variable))
                    (apply
                      (name)
                      (variable)))
                  (variable))))))
        (type_binder
          (list
            (apply
              (name)
              (variable)))))
      (match
        (variable)))
    (bind
      (variable)
      (match
        (lambda
          (patterns
            (type_binder
              (variable))
            (variable)
            (type_binder
              (variable)))
          (variable))))))

================================================================================
pat: cond in viewpat
================================================================================

a (if a then a else a -> a) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (view_pattern
            (conditional
              (variable)
              (variable)
              (variable))
            (variable))))
      (match
        (variable)))))

================================================================================
pat: lambda in viewpat
================================================================================

a (\ a -> a -> a) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (view_pattern
            (lambda
              (patterns
                (variable))
              (variable))
            (variable))))
      (match
        (variable)))))

================================================================================
pat: complex viewpat
================================================================================

a (a <> if a then a else a -> a) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (view_pattern
            (infix
              (variable)
              (operator)
              (conditional
                (variable)
                (variable)
                (variable)))
            (variable))))
      (match
        (variable)))))

================================================================================
pat: error: annotation in viewpat
================================================================================

a (a :: A -> A {}) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (signature
            (variable)
            (function
              (name)
              (name)))
          (ERROR)))
      (match
        (variable)))))

================================================================================
pat: multi viewpat
================================================================================

a (a -> a -> a -> A) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (view_pattern
            (variable)
            (view_pattern
              (variable)
              (view_pattern
                (variable)
                (constructor))))))
      (match
        (variable)))))

================================================================================
pat: ticked infix
================================================================================

a (a `A` a) = a
a (a `A.A` a) = a
a (A a `A` A a) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (infix
            (variable)
            (infix_id
              (constructor))
            (variable))))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (parens
          (infix
            (variable)
            (infix_id
              (qualified
                (module
                  (module_id))
                (constructor)))
            (variable))))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (parens
          (infix
            (apply
              (constructor)
              (variable))
            (infix_id
              (constructor))
            (apply
              (constructor)
              (variable)))))
      (match
        (variable)))))

================================================================================
pat: prefix tuple con
================================================================================

a ((,) a a) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (apply
            (apply
              (prefix_tuple)
              (variable))
            (variable))))
      (match
        (variable)))))

================================================================================
pat: bang in case match
================================================================================

a = case a of !a -> a

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

(haskell
  (declarations
    (bind
      (variable)
      (match
        (case
          (variable)
          (alternatives
            (alternative
              (strict
                (variable))
              (match
                (variable)))))))))

================================================================================
pat: qualified infix
================================================================================

a (a A.:++ a) = a
a (a A.A.:++ a A.A.:++ a) = a
a (A a A.:++ A a) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (parens
          (infix
            (variable)
            (qualified
              (module
                (module_id))
              (constructor_operator))
            (variable))))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (parens
          (infix
            (variable)
            (qualified
              (module
                (module_id)
                (module_id))
              (constructor_operator))
            (infix
              (variable)
              (qualified
                (module
                  (module_id)
                  (module_id))
                (constructor_operator))
              (variable)))))
      (match
        (variable)))
    (function
      (variable)
      (patterns
        (parens
          (infix
            (apply
              (constructor)
              (variable))
            (qualified
              (module
                (module_id))
              (constructor_operator))
            (apply
              (constructor)
              (variable)))))
      (match
        (variable)))))

================================================================================
pat: explicit type binder
================================================================================

a (type a) (type (A a)) = a

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

(haskell
  (declarations
    (function
      (variable)
      (patterns
        (explicit_type
          (variable))
        (explicit_type
          (parens
            (apply
              (name)
              (variable)))))
      (match
        (variable)))))
