================================================================================
context: multi, multi line
================================================================================

a ::
  A a a =>
  (A a, A a) =>
  (A => a a) ->
  A a ->
  a

---

(haskell
 (signature
  (variable)
  (context
   (constraint (class_name (type)) (type_name (type_variable)) (type_name (type_variable)))
   (context
    (constraint (class_name (type)) (type_name (type_variable)))
    (comma)
    (constraint (class_name (type)) (type_name (type_variable)))
    (fun
     (type_parens
      (context (constraint (class_name (type)))
      (type_apply (type_name (type_variable)) (type_name (type_variable)))))
     (fun (type_apply (type_name (type)) (type_name (type_variable))) (type_name (type_variable))))))))

================================================================================
context: multi, single line
================================================================================

a :: A a a => (A a, A a) => a

---

(haskell
 (signature
  (variable)
  (context
   (constraint (class_name (type)) (type_name (type_variable)) (type_name (type_variable)))
   (context
    (constraint (class_name (type)) (type_name (type_variable)))
    (comma)
    (constraint (class_name (type)) (type_name (type_variable)))
    (type_name (type_variable))))))

================================================================================
context: operator
================================================================================

a :: a ++ a => a

---

(haskell
 (signature
  name: (variable)
  type: (context
   (constraint (type_infix left: (type_name (type_variable)) op: (type_operator) right: (type_name (type_variable))))
   (type_name (type_variable)))))

================================================================================
context: implicit
================================================================================

a :: (?aaa :: a -> a -> a) => a -> a

---

(haskell
 (signature
  (variable)
  (context
   (implicit_param
    (implicit_parid)
    (fun (type_name (type_variable)) (fun (type_name (type_variable)) (type_name (type_variable)))))
   (fun
    (type_name (type_variable))
    (type_name (type_variable))))))

================================================================================
context: forall/context in constraint
================================================================================

a :: (forall a . A => A) => A

---

(haskell
 (signature
  (variable)
  (context
   (forall
    (quantifiers (type_variable))
    (context (constraint (class_name (type)))
     (constraint (class_name (type)))))
   (type_name (type)))))

================================================================================
context: multiple nested foralls/contexts in constraint
================================================================================

a :: (forall a . forall a . (forall a . A => A) => forall a . A => A) => A

---

(haskell
 (signature
  (variable)
  (context
   (forall
    (quantifiers (type_variable))
    (forall
     (quantifiers (type_variable))
     (context
      (forall
       (quantifiers (type_variable))
       (context
        (constraint (class_name (type)))
        (constraint (class_name (type)))))
      (forall
       (quantifiers (type_variable))
       (context
        (constraint (class_name (type)))
        (constraint (class_name (type))))))))
   (type_name (type)))))

================================================================================
context: double parenthesis
================================================================================

a :: ((A)) => A

---

(haskell (signature (variable) (context (constraint (class_name (type))) (type_name (type)))))
