================================================================================
instance: minimal
================================================================================

instance A a

---

(haskell (instance (instance_head (class_name (type)) (type_name (type_variable)))))

================================================================================
instance: type
================================================================================

instance A A a A

---

(haskell
 (instance
  (instance_head
   (class_name (type))
   (type_name (type))
   (type_name (type_variable))
   (type_name (type)))))

================================================================================
instance: forall
================================================================================

instance forall a (a :: *) . A

---

(haskell
 (instance
  (forall
   (quantifiers
    (type_variable)
    (annotated_type_variable (type_variable) (type_star)))
  )
  (instance_head (class_name (type)))))

================================================================================
instance: context
================================================================================

instance A a => A
instance (A a, A a) => A

---

(haskell
 (instance
  (context (constraint (class_name (type)) (type_name (type_variable))))
  (instance_head (class_name (type))))
 (instance
  (context
   (constraint (class_name (type)) (type_name (type_variable)))
   (comma)
   (constraint (class_name (type)) (type_name (type_variable)))
  )
  (instance_head (class_name (type)))))

================================================================================
instance: method
================================================================================

instance A a where a a = Just a

---

(haskell
 (instance
  (instance_head (class_name (type)) (type_name (type_variable)))
  (where)
  (function
   (variable)
   (patterns (pat_name (variable)))
   (exp_apply (exp_name (constructor)) (exp_name (variable))))))

================================================================================
instance: signature
================================================================================

instance A a where
  a :: A a => a -> a
  a a = a

---

(haskell
 (instance
  (instance_head (class_name (type)) (type_name (type_variable)))
  (where)
  (signature
   (variable)
   (context
    (constraint (class_name (type)) (type_name (type_variable)))
    (fun (type_name (type_variable)) (type_name (type_variable)))))
  (function
   (variable)
   (patterns (pat_name (variable)))
   (exp_name (variable)))))

================================================================================
instance: equality constraint
================================================================================

instance A a ~ A a => A a
instance A ~~ A => A a

---

(haskell
 (instance
  (context
   (constraint
    (type_infix
     left: (type_apply (type_name (type)) (type_name (type_variable)))
     op: (type_operator)
     right: (type_apply (type_name (type)) (type_name (type_variable)))))
  )
  (instance_head class: (class_name (type)) (type_name (type_variable))))
 (instance
  (context
   (constraint
    (type_infix
     left: (type_name (type))
     op: (type_operator)
     right: (type_name (type))))
  )
  (instance_head class: (class_name (type)) (type_name (type_variable)))))

================================================================================
instance: associated type instance
================================================================================

instance A where
  type A A a = A a
  type instance A @A a = A

---

(haskell
 (instance
  (instance_head
   (class_name (type)))
  (where)
  (type_instance
   (type_name (type))
   (type_name (type))
   (type_name (type_variable))
   (type_apply (type_name (type)) (type_name (type_variable))))
  (type_instance
   (type_name (type))
   (type_invisible (type_name (type)))
   (type_name (type_variable))
   (type_name (type)))))

================================================================================
instance: associated data instance
================================================================================

instance A where
  data A a = A a | A { a :: A }
  data instance ∀ a . A a => A a = A

---

(haskell
 (instance
  (instance_head (class_name (type)))
  (where)
  (data_instance
   (type_apply
    (type_name (type))
    (type_name (type_variable)))
   (constructors
    (data_constructor (constructor) (type_name (type_variable)))
    (data_constructor_record
     (constructor)
     (record_fields (field (variable) (type_name (type)))))))
  (data_instance
   (forall (quantifiers (type_variable)))
   (context (constraint (class_name (type)) (type_name (type_variable))))
   (type_apply
    (type_name (type))
    (type_name (type_variable)))
   (constructors (data_constructor (constructor))))))

================================================================================
instance: infix pattern lhs method
================================================================================

instance A where
  a == a = a

---

(haskell
 (instance
  (instance_head (class_name (type)))
  (where)
  (function
   (infix (pat_name (variable)) (varop (operator)) (pat_name (variable)))
   (exp_name (variable)))))

================================================================================
instance: standalone deriving
================================================================================

deriving instance A (A a)
deriving instance A ++ A
deriving instance A a => A (A a)
deriving instance (A a, A a a) => A (A a)

---

(haskell
 (deriving_declaration (instance_head
   (class_name (type))
   (type_parens (type_apply (type_name (type)) (type_name (type_variable))))))
 (deriving_declaration
  (instance_head
   (type_infix
    (type_name (type))
    (type_operator)
    (type_name (type)))))
 (deriving_declaration
  (context (constraint (class_name (type)) (type_name (type_variable))))
  (instance_head
   (class_name (type))
   (type_parens (type_apply (type_name (type)) (type_name (type_variable))))))
 (deriving_declaration
  (context
   (constraint (class_name (type)) (type_name (type_variable)))
   (comma)
   (constraint (class_name (type)) (type_name (type_variable)) (type_name (type_variable)))
  )
  (instance_head
   (class_name (type))
   (type_parens (type_apply (type_name (type)) (type_name (type_variable)))))))


================================================================================
instance: deriving via
================================================================================

deriving via (A a) instance A a

---

(haskell
 (deriving_declaration
  (via (type_parens (type_apply (type_name (type)) (type_name (type_variable)))))
  (instance_head (class_name (type)) (type_name (type_variable)))))
