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

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

---

(haskell
 (function
   name: (variable)
   patterns: (patterns
    (pat_name (variable))
    (pat_parens
     (pat_infix
      (pat_name (variable))
      (constructor_operator)
      (pat_infix (pat_name (variable)) (constructor_operator) (pat_name (variable)))))
    (pat_tuple
     (pat_name (variable))
     (comma)
     (pat_name (variable))
     (comma)
     (pat_tuple (pat_name (variable)) (comma) (pat_list (pat_name (variable))))))
  rhs: (exp_name (variable))))

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

a A = a
a (A a) = a

---

(haskell
 (function (variable) (patterns (pat_name (constructor))) (exp_name (variable)))
 (function
  (variable)
  (patterns (pat_parens (pat_apply (pat_name (constructor)) (pat_name (variable)))))
  (exp_name (variable))))

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

a (a :++ a) = a

---

(haskell
 (function
  (variable)
  (patterns (pat_parens (pat_infix (pat_name (variable)) (constructor_operator) (pat_name (variable)))))
  (exp_name (variable))))

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

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

---

(haskell
 (function
  (variable)
  (patterns
   (pat_as (variable) (pat_parens (pat_apply (pat_name (constructor)) (pat_name (variable)))))
   (pat_as (variable) (pat_parens (pat_apply (pat_name (constructor)) (pat_name (variable))))))
  (exp_name (variable))))

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

a (A _) _ = a

---

(haskell
 (function
  (variable)
  (patterns
   (pat_parens (pat_apply (pat_name (constructor)) (pat_wildcard)))
   (pat_wildcard))
  (exp_name (variable))))

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

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

---

(haskell
 (function (variable) (patterns (pat_literal (integer)) (pat_literal (integer))) (exp_literal (integer)))
 (function (variable) (patterns (pat_literal (string)) (pat_literal (string))) (exp_name (variable)))
 (function (variable) (patterns (pat_literal (char)) (pat_literal (char))) (exp_name (variable)))
 (function (variable) (patterns (pat_literal (float)) (pat_literal (float))) (exp_literal (float))))

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

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

---

(haskell
 (function (variable) (patterns (pat_record (pat_name (constructor)) (pat_fields))) (exp_name (variable)))
 (function
  (variable)
  (patterns
   (pat_record
    (pat_name (constructor))
    (pat_fields (pat_field (wildcard)))))
   (exp_name (variable)))
 (function
  (variable)
  (patterns
   (pat_as
    (variable)
    (pat_record
     (pat_name (constructor))
     (pat_fields
      (pat_field (variable) (pat_name (variable)))
      (comma)
      (pat_field (variable) (pat_name (variable)))
      (comma)
      (pat_field (variable)) (comma) (pat_field (wildcard))))))
  (exp_name (variable))))

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

a ~a = a
a ~(~a) = a
a ~(~(a, a), a) = a

---

(haskell
 (function
  (variable) (patterns (pat_irrefutable (pat_name (variable)))) (exp_name (variable)))
 (function
  (variable) (patterns (pat_irrefutable (pat_parens (pat_irrefutable (pat_name (variable))))))
  (exp_name (variable)))
 (function
  (variable)
  (patterns (pat_irrefutable
    (pat_tuple
     (pat_irrefutable (pat_tuple (pat_name (variable)) (comma) (pat_name (variable))))
     (comma)
     (pat_name (variable)))))
  (exp_name (variable))))

================================================================================
pat: view pattern in function lhs
================================================================================

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

---

(haskell
 (function
  (variable)
  (patterns
   (pat_parens
    (pat_view
     (exp_apply (exp_name (variable)) (exp_name (variable)))
     (pat_apply (pat_name (constructor)) (pat_name (variable)) (pat_name (variable))))))
  (exp_name (variable)))
  (function
   (variable)
   (patterns
    (pat_tuple
     (pat_view (exp_name (variable)) (pat_name (variable)))
     (comma)
     (pat_view (exp_name (variable)) (pat_name (variable)))))
   (exp_name (variable))))

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

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

---

(haskell
 (function
  (variable)
  (exp_lambda
   (pat_parens (pat_view (exp_name (variable)) (pat_name (variable))))
   (exp_name (variable)))))

================================================================================
pat: infix pattern in decl lhs
================================================================================

A a == A a = a == a

---

(haskell
 (function
  infix: (infix
   lhs: (pat_apply (pat_name (constructor)) (pat_name (variable)))
   op: (varop (operator))
   rhs: (pat_apply (pat_name (constructor)) (pat_name (variable))))
  rhs: (exp_infix (exp_name (variable)) (operator) (exp_name (variable)))))

================================================================================
pat: infix pattern variable
================================================================================

a |> a = a

---

(haskell
 (function
  (infix (pat_name (variable)) (varop (operator)) (pat_name (variable)))
  (exp_name (variable))))

================================================================================
pat: tuple pattern function
================================================================================

(a, a) = a

---

(haskell (function (pat_tuple (pat_name (variable)) (comma) (pat_name (variable))) (exp_name (variable))))

================================================================================
pat: con application pattern function
================================================================================

A a = a

---

(haskell (function (pat_apply (pat_name (constructor)) (pat_name (variable))) (exp_name (variable))))

================================================================================
pat: parens con application pattern function
================================================================================

(A a) = a

---

(haskell
 (function
  pattern: (pat_parens (pat_apply (pat_name (constructor)) (pat_name (variable))))
  rhs: (exp_name (variable))))

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

a (A{}) = a


---

(haskell
 (function
  (variable) (patterns (pat_parens (pat_record (pat_name (constructor)) (pat_fields))))
  (exp_name (variable))))

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

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

---

(haskell
 (function
  name: (variable)
  patterns: (patterns (pat_name (variable)))
  (guard_equation
   (guards
    (guard (exp_infix (exp_name (variable)) (operator) (exp_literal (integer))))
    (comma)
    (guard (exp_infix (exp_name (variable)) (operator) (exp_literal (integer)))))
   (exp_name (constructor)))
  (guard_equation
   (guards
    (guard
     (pattern_guard
      (pat_infix
       (pat_apply
        (pat_name (constructor))
        (pat_parens
         (pat_apply
         (pat_name (constructor))
         (pat_record con: (pat_name (constructor)) fields: (pat_fields (pat_field (wildcard))))
         (pat_wildcard))))
       (constructor_operator)
       (pat_name (variable)))
      (exp_name (variable)))))
   (exp_name (constructor)))
  (guard_equation
   (guards (guard (exp_name (variable))))
   (exp_name (constructor)))))

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

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

---

(haskell
 (function
  (variable)
  (patterns
   (pat_record
    (pat_name (constructor))
    (pat_fields (pat_field (variable) (pat_view (exp_name (variable)) (pat_name (variable)))))))
  (exp_name (variable))))

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

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

---

(haskell
 (function
  (variable)
  (patterns (pat_unboxed_tuple (pat_name (variable)) (comma) (pat_name (variable)) (comma) (pat_name (variable))))
  (exp_name (variable))))

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

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

---

(haskell
 (function
  (variable)
  (patterns
   (pat_unboxed_sum (pat_unboxed_tuple)))
  (exp_name (variable))))

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

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

---

(haskell
 (function
  (variable)
  (patterns (pat_parens (pat_typed (pat_name (variable)) (type_name (type)))))
  (exp_name (variable)))
 (function
  (variable)
  (exp_do
   (stmt
    (let
     (decls
      (function
       (pat_tuple (pat_typed (pat_name (variable)) (type_name (type))) (comma) (pat_name (variable)))
       (exp_name (variable)))))))))

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

a = do
  a :: A <- a

---

(haskell
 (function
  name: (variable)
  rhs: (exp_do
   (stmt (bind_pattern (pat_typed pattern: (pat_name (variable)) type: (type_name (type))) (exp_name (variable)))))))

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

a :: A = a

---

(haskell (function (pat_typed (pat_name (variable)) (type_name (type))) (exp_name (variable))))

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

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

---

(haskell
 (function
  (variable)
  (exp_do
   (stmt
    (bind_pattern
     (pat_parens (pat_view (exp_name (variable)) (pat_name (variable))))
     (exp_name (variable)))))))

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

a $(a) = a

---

(haskell (function (variable) (patterns (splice (exp_parens (exp_name (variable))))) (exp_name (variable))))

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

a [a|a|] = a

---

(haskell
 (function
  (variable)
  (patterns (quasiquote (quasiquote_start) (quoter) (quasiquote_bar) (quasiquote_body)))
  (exp_name (variable))))

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

a (++) = a

---

(haskell (function (variable) (patterns (pat_name (operator))) (exp_name (variable))))

================================================================================
pat: negation with parens
================================================================================

f (-(a)) = a

---

(haskell
 (function
  (variable)
  (patterns
   (pat_parens
    (pat_negation (pat_parens (pat_name (variable))))))
  (exp_name (variable))))

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

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

---

(haskell
 (function
  (variable)
  (patterns
   (pat_parens
    (pat_apply
     (pat_name (constructor))
     (pat_type_binder (type_name (type_variable)))
     (pat_type_binder (type_name (annotated_type_variable (type_variable) (type_name (type_variable)))))
     (pat_type_binder
      (type_parens
       (type_apply
        (type_name (type))
        (type_name (type_variable)))
       (kind (type_name (type_variable)))))
     (pat_type_binder
      (type_parens
       (forall
        (quantifiers (type_variable))
        (type_apply
         (type_name (type))
         (type_name (type_variable))))
       (kind (type_name (type_variable))))))))
  (exp_name (variable))))
