================================================================================
pattern synonym: unidirectional simple
================================================================================

pattern A a <- a:as

---

(haskell
 (pattern_synonym
  (equation
   (pat_apply (pat_name (constructor)) (pat_name (variable)))
   (pat_infix (pat_name (variable)) (constructor_operator) (pat_name (variable))))))

================================================================================
pattern synonym: unidirectional strict
================================================================================

pattern A a = A !a

---

(haskell
 (pattern_synonym
  (equation
   (pat_apply (pat_name (constructor)) (pat_name (variable)))
   (pat_apply (pat_name (constructor)) (pat_strict (pat_name (variable)))))))

================================================================================
pattern synonym: explicit bidirectional list
================================================================================

pattern HeadC a <- a:as where
  HeadC a = [a]

---

(haskell
 (pattern_synonym
  (equation
   (pat_apply (pat_name (constructor)) (pat_name (variable)))
   (pat_infix (pat_name (variable)) (constructor_operator) (pat_name (variable)))
   (where)
   (pat_apply (pat_name (constructor)) (pat_name (variable)))
   (exp_list (exp_name (variable))))))

================================================================================
pattern synonym: explicit bidirectional strict
================================================================================

pattern A a <- A !a where
  A !a = A a

---

(haskell
 (pattern_synonym
  (equation
   (pat_apply (pat_name (constructor)) (pat_name (variable)))
   (pat_apply (pat_name (constructor)) (pat_strict (pat_name (variable))))
   (where)
   (pat_apply (pat_name (constructor)) (pat_strict (pat_name (variable))))
   (exp_apply (exp_name (constructor)) (exp_name (variable))))))

================================================================================
pattern synonym: explicit bidirectional record
================================================================================

pattern A { a } <- A a where
  A a = if a >= 0 then a else a

---

(haskell
 (pattern_synonym
  (equation
   lhs: (pat_record
    con: (pat_name (constructor))
    fields: (pat_fields (pat_field (variable))))
   rhs: (pat_apply (pat_name (constructor)) (pat_name (variable)))
   (where)
   (pat_apply (pat_name (constructor)) (pat_name (variable)))
   rhs: (exp_cond
     if: (exp_infix (exp_name (variable)) (operator) (exp_literal (integer)))
     then: (exp_name (variable))
     else: (exp_name (variable))))))

================================================================================
pattern synonym: explicit bidirectional guards
================================================================================

pattern A a <- A a where
  A a
    | a >= 0    = (A a)
    | otherwise = (A a)

---

(haskell
 (pattern_synonym
  (equation
   (pat_apply (pat_name (constructor)) (pat_name (variable)))
   (pat_apply (pat_name (constructor)) (pat_name (variable)))
   (where)
   (pat_apply (pat_name (constructor)) (pat_name (variable)))
   (guard_equation
    (guards (guard (exp_infix (exp_name (variable)) (operator) (exp_literal (integer)))))
    (exp_parens (exp_apply (exp_name (constructor)) (exp_name (variable)))))
   (guard_equation
    (guards (guard (exp_name (variable))))
    (exp_parens (exp_apply (exp_name (constructor)) (exp_name (variable))))))))

================================================================================
pattern synonym: signature
================================================================================

pattern A :: A -> A -> (A, A)

---

(haskell
 (pattern_synonym
  (signature
   (constructor)
   (fun
    (type_name (type))
    (fun
     (type_name (type))
     (type_tuple
      (type_name (type))
      (comma)
      (type_name (type))))))))

================================================================================
pattern synonym: unidirectional record
================================================================================

pattern A {a, a} = (a, a)

---

(haskell
 (pattern_synonym
  (equation
   (pat_record (pat_name (constructor)) (pat_fields (pat_field (variable)) (comma) (pat_field (variable))))
   (pat_tuple (pat_name (variable)) (comma) (pat_name (variable))))))

================================================================================
pattern synonym: operator
================================================================================

pattern (:->) :: A
pattern a :-> b <- a

---

(haskell
 (pattern_synonym (signature (constructor_operator) type: (type_name (type))))
 (pattern_synonym
  (equation
   lhs: (pat_infix (pat_name (variable)) (constructor_operator) (pat_name (variable)))
   rhs: (pat_name (variable)))))
