================================================================================
class: minimal
================================================================================

class A a

---

(haskell (class (class_head class: (class_name (type)) (type_name (type_variable)))))

================================================================================
class: context variants
================================================================================

class A a => Read a
class (A a, A a) => A a

---

(haskell
 (class
  (context
   (constraint (class_name (type)) (type_name (type_variable)))
  )
  (class_head (class_name (type)) (type_name (type_variable))))
 (class
  (context
   (constraint (class_name (type)) (type_name (type_variable)))
   (comma)
   (constraint (class_name (type)) (type_name (type_variable)))
  )
  (class_head (class_name (type)) (type_name (type_variable)))))

================================================================================
class: method with context
================================================================================

class A a where a :: A a => a -> a

---

(haskell
 (class
  (class_head class: (class_name (type)) (type_name (type_variable)))
  (class_body
   (where)
   (signature
    name: (variable)
    type: (context
     (constraint class: (class_name (type)) (type_name (type_variable)))
     (fun (type_name (type_variable)) (type_name (type_variable))))))))

================================================================================
class: braces
================================================================================

class Foo a where {
  a :: a;
  a :: a;
}

---

(haskell
 (class
  (class_head (class_name (type)) (type_name (type_variable)))
  (class_body
   (where)
   (signature (variable) (type_name (type_variable)))
   (signature (variable) (type_name (type_variable))))))

================================================================================
class: fixity
================================================================================

class A where
  infixl `op`
  a :: Int
  infixr 7 `op`
  a = a
  infix 7 `op`, `ip`, `ap`
  infix <$>
  infix 7 <$>
  infix 7 :
  infix 7 :.
  infix 7 :<:

---

(haskell
 (class
  (class_head (class_name (type)))
  (class_body
   (where)
   (fixity (varop (variable)))
   (signature (variable) (type_name (type)))
   (fixity (integer) (varop (variable)))
   (function (variable) (exp_name (variable)))
   (fixity (integer) (varop (variable)) (comma) (varop (variable)) (comma) (varop (variable)))
   (fixity (varop (operator)))
   (fixity (integer) (varop (operator)))
   (fixity (integer) (constructor_operator))
   (fixity (integer) (constructor_operator))
   (fixity (integer) (constructor_operator)))))

================================================================================
class: multi method operator
================================================================================

class A where
  (<), (<=), (>=), (>) :: a

---

(haskell
 (class
  (class_head (class_name (type)))
  (class_body
   (where)
   (signature
    (operator)
    (comma)
    (operator)
    (comma)
    (operator)
    (comma)
    (operator)
    (type_name (type_variable))))))

================================================================================
class: multi param
================================================================================

class A a a a

---

(haskell (class (class_head (class_name (type)) (type_name (type_variable)) (type_name (type_variable)) (type_name (type_variable)))))

================================================================================
class: default signature
================================================================================

class A where
  a :: Int
  default a :: Int

---

(haskell
 (class
  (class_head (class_name (type)))
  (class_body
   (where)
   (signature (variable) (type_name (type)))
   (default_signature (signature (variable) (type_name (type)))))))

================================================================================
class: type_variable kind
================================================================================

class A (a :: [*] -> k)

---

(haskell
 (class
  (class_head
   (class_name (type))
   (type_name
    (annotated_type_variable
     (type_variable)
     (fun (type_list (type_star)) (type_name (type_variable))))))))

================================================================================
class: associated family
================================================================================

class A a where
  type A a :: a
  type A a = A
  type family A a :: a

---

(haskell
 (class
  (class_head (class_name (type)) (type_name (type_variable)))
  (class_body
   (where)
   (decl_type (type) (type_variable) (type_name (type_variable)))
   (decl_type (type) (type_variable) (type_name (type)))
   (decl_tyfam_sig (type) (type_variable) (type_name (type_variable))))))

================================================================================
class: associated data
================================================================================

class A a where
  data A a
  data family A a :: * -> Type

---

(haskell
 (class
  (class_head (class_name (type)) (type_name (type_variable)))
  (class_body
   (where)
   (data_family (type) (type_variable))
   (data_family
    (type)
    (type_variable)
    (fun (type_star) (type_name (type)))))))

================================================================================
class: fundeps
================================================================================

class A | a -> a a, a a -> a

---

(haskell
 (class
  (class_head class: (class_name (type)))
  (fundeps
   (fundep (type_variable) (type_variable) (type_variable))
   (comma)
   (fundep (type_variable) (type_variable) (type_variable)))))

================================================================================
class: infix operator name
================================================================================

class a ++ b

---

(haskell
 (class
  (class_head
   (type_infix
    left: (type_name (type_variable))
    op: (type_operator)
    right: (type_name (type_variable))))))
