=========================================
Type Class Declarations
=========================================

class Show a where {}
class Show a b where {}

---

(module
  (type_class_declaration (type_class_identifier) (type_variable_identifier) (where))
  (type_class_declaration (type_class_identifier) (type_variable_identifier) (type_variable_identifier) (where)))

=========================================
Type Class Declarations With Context
=========================================

class Show a => Read a where {}
class (Show a, Eq a) => Read a where {}

---

(module
  (type_class_declaration
    (context (context_pattern (class (type_class_identifier) (type_variable_identifier))))
    (type_class_identifier)
    (type_variable_identifier)
    (where))
  (type_class_declaration
    (context
      (context_pattern (class (type_class_identifier) (type_variable_identifier)))
      (context_pattern (class (type_class_identifier) (type_variable_identifier))))
    (type_class_identifier)
    (type_variable_identifier)
    (where)))

=========================================
Type Class Declarations With Body
=========================================

class Foo a where {
  op :: Num b => a -> b -> a;
  op' :: (Num a, Num b) => a -> b -> a;
}

---

(module
  (type_class_declaration
    (type_class_identifier)
    (type_variable_identifier)
    (where
      (type_signature
        (variable_identifier)
        (annotation)
        (context (context_pattern (class (type_class_identifier) (type_variable_identifier))))
        (function_type
          (type (type_variable_identifier))
          (function_type
            (type (type_variable_identifier))
            (type (type_variable_identifier)))))
      (type_signature
        (variable_identifier)
        (annotation)
        (context
          (context_pattern (class (type_class_identifier) (type_variable_identifier)))
          (context_pattern (class (type_class_identifier) (type_variable_identifier))))
        (function_type
          (type (type_variable_identifier))
          (function_type
            (type (type_variable_identifier))
            (type (type_variable_identifier))))))))

=========================================
Type Class Declarations With Fixity
=========================================

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

---

(module
  (type_class_declaration
    (type_class_identifier)
    (type_variable_identifier)
    (where
      (fixity_declaration (variable_operator (infix_variable_identifier)))
      (fixity_declaration (integer) (variable_operator (infix_variable_identifier)))
      (fixity_declaration
        (integer)
        (variable_operator (infix_variable_identifier))
        (variable_operator (infix_variable_identifier))
        (variable_operator (infix_variable_identifier)))
      (fixity_declaration (variable_operator (variable_symbol)))
      (fixity_declaration (integer) (variable_operator (variable_symbol)))
      (fixity_declaration (integer) (constructor_operator (constructor_symbol)))
      (fixity_declaration (integer) (constructor_operator (constructor_symbol)))
      (fixity_declaration (integer) (constructor_operator (constructor_symbol))))))

=========================================
Type Class Declarations With Multiple Operators
=========================================

class (Eq a) => Ord a where
  compare              :: a -> a -> Ordering
  (<), (<=), (>=), (>) :: a -> a -> Bool
  max, min             :: a -> a -> a
  id                   :: a

---

(module
  (type_class_declaration
    (context (context_pattern (class (type_class_identifier) (type_variable_identifier))))
    (type_class_identifier)
    (type_variable_identifier)
    (where
      (type_signature
        (variable_identifier)
        (annotation)
        (function_type
          (type (type_variable_identifier))
          (function_type
            (type (type_variable_identifier))
            (type (type_constructor_identifier)))))
      (type_signature
        (variable_operator (variable_symbol))
        (variable_operator (variable_symbol))
        (variable_operator (variable_symbol))
        (variable_operator (variable_symbol))
        (annotation)
        (function_type
          (type (type_variable_identifier))
          (function_type
            (type (type_variable_identifier))
            (type (type_constructor_identifier)))))
      (type_signature
        (variable_identifier)
        (variable_identifier)
        (annotation)
        (function_type
          (type (type_variable_identifier))
          (function_type
            (type (type_variable_identifier))
            (type (type_variable_identifier)))))
      (type_signature
        (variable_identifier)
        (annotation)
        (type_variable_identifier)))))

=========================================
Multi-param Type Class Declarations
=========================================

class Bar a b m => Baz a b m where {}

---

(module
  (type_class_declaration
    (context
      (context_pattern
        (class
          (type_class_identifier)
          (type_variable_identifier)
          (type_variable_identifier)
          (type_variable_identifier))))
    (type_class_identifier)
    (type_variable_identifier)
    (type_variable_identifier)
    (type_variable_identifier)
    (where)))

=========================================
Type Class Declarations With Default Signature
=========================================

class Bar baz where
  foo :: wiz -> Baz
  default foo :: wiz -> Baz

---

(module
  (type_class_declaration
    (type_class_identifier)
    (type_variable_identifier)
    (where
      (type_signature
        (variable_identifier)
        (annotation)
        (function_type
        (type (type_variable_identifier))
        (type (type_constructor_identifier))))
    (default_signature
      (variable_identifier)
      (annotation)
      (function_type
      (type (type_variable_identifier))
      (type (type_constructor_identifier)))))))

=========================================
Type Class Declarations With Annotated Type Variable
=========================================

class Bar (baz :: Foo) where
class Effectful (m :: [* -> *] -> * -> *) where

---

(module
  (type_class_declaration
    (type_class_identifier)
    (annotated_type_variable
      (type_variable_identifier)
      (annotation)
      (type_constructor_identifier))
    (where))
  (type_class_declaration
    (type_class_identifier)
    (annotated_type_variable
      (type_variable_identifier)
      (annotation)
      (kind_function_type
        (kind
          (kind_list_type
            (kind_function_type
              (kind (star))
              (kind (star)))))
        (kind_function_type
          (kind (star))
          (kind (star)))))
    (where)))

=========================================
Type Class Declarations With Type Annotated Type Synonym
=========================================

class Foo bar where
  type Baz wiz :: Wax

---

(module
  (type_class_declaration
    (type_class_identifier)
    (type_variable_identifier)
    (where
      (type_synonym_declaration
        (type_constructor_identifier)
        (type_variable_identifier)
        (type_signature
          (annotation)
          (type_constructor_identifier))))))

=========================================
Type Class Declarations With Type Family Declaration
=========================================

class Bar baz => Foo fax where
  type family Woo a :: [* -> *]

---

(module
  (type_class_declaration
    (context
      (context_pattern
        (class
          (type_class_identifier)
          (type_variable_identifier))))
    (type_class_identifier)
    (type_variable_identifier)
    (where
      (type_family_declaration
        (type_constructor_identifier)
        (type_variable_identifier)
        (kind_signature
          (annotation)
          (kind_list_type
            (kind_function_type
              (kind (star))
              (kind (star)))))))))

=========================================
Type Class Declarations With Functional Dependencies
=========================================

class (Monad a, Show b) => Foo a b c | a -> c, b -> c where
  d :: a b

---

(module
  (type_class_declaration
    (context
      (context_pattern
        (class (type_class_identifier) (type_variable_identifier)))
      (context_pattern
        (class (type_class_identifier) (type_variable_identifier))))
    (type_class_identifier)
    (type_variable_identifier)
    (type_variable_identifier)
    (type_variable_identifier)
    (functional_dependency
      (function_type
        (type (type_variable_identifier))
        (type (type_variable_identifier)))
      (function_type
        (type (type_variable_identifier))
        (type (type_variable_identifier))))
    (where
      (type_signature
        (variable_identifier)
        (annotation)
        (type_variable_identifier)
        (type_variable_identifier)))))
