=================================================
Function Declarations With Type Variables
=================================================

f num1 num2 = num2

---

 (module
  (function_declaration
    (variable_identifier)
    (variable_identifier)
    (variable_identifier)
    (function_body
      (variable_identifier))))

=================================================
Function Declarations With Simple Constructors
=================================================

f (Ex 1) = Ex 1

---

(module
  (function_declaration
    (variable_identifier)
    (parenthesized_pattern
      (constructor_pattern
        (constructor_identifier)
        (integer)))
    (function_body
      (function_application
        (constructor_identifier)
        (integer)))))

=================================================
Function Declarations With @
=================================================

f n@num1 x@num2 = x

---

(module
  (function_declaration
    (variable_identifier)
    (as_pattern
      (variable_identifier)
      (variable_identifier))
    (as_pattern
      (variable_identifier)
      (variable_identifier))
    (function_body (variable_identifier))))

=================================================
Function Declarations With _ (wildcard)
=================================================

f _ num2 = num2

---

(module
  (function_declaration
    (variable_identifier)
    (wildcard)
    (variable_identifier)
    (function_body (variable_identifier))))

=================================================
Function Declarations With Literals
=================================================

f 1 2 = 3
f "hello" "world" = "goodbye"
f 'a' 'b' = 'c'
f 1.0 2.0 = 3.0

---

(module
  (function_declaration
    (variable_identifier)
    (integer)
    (integer)
    (function_body (integer)))
  (function_declaration
    (variable_identifier)
    (string)
    (string)
    (function_body (string)))
  (function_declaration
    (variable_identifier)
    (char)
    (char)
    (function_body (char)))
  (function_declaration
    (variable_identifier)
    (float)
    (float)
    (function_body (float))))

=================================================
Function Declarations With Field Labels
=================================================

f Ex { a = 1 } = 1
f Ex { a = 1, b = 2 } = 2
f Ex {} = 2

---

(module
  (function_declaration
    (variable_identifier)
    (labeled_pattern
      (constructor_identifier)
      (field_pattern (variable_identifier) (integer)))
    (function_body (integer)))
  (function_declaration
    (variable_identifier)
    (labeled_pattern
      (constructor_identifier)
      (field_pattern (variable_identifier) (integer))
      (field_pattern (variable_identifier) (integer)))
    (function_body (integer)))
  (function_declaration
    (variable_identifier)
    (labeled_pattern
      (constructor_identifier))
    (function_body (integer))))

=================================================
Function Declarations With Named Field Puns
=================================================

data Blob = Blob { start :: Int, end :: Int }

f Blob{start, end} = [start, end]

---

(module
  (algebraic_datatype_declaration
    (type_constructor_identifier)
    (constructors
      (record_data_constructor
        (constructor_identifier)
        (fields
          (field (variable_identifier) (annotation) (type_constructor_identifier))
          (field (variable_identifier) (annotation) (type_constructor_identifier))))))
  (function_declaration
    (variable_identifier)
    (labeled_pattern
      (constructor_identifier)
      (named_field_pun (variable_identifier))
      (named_field_pun (variable_identifier)))
    (function_body (list_expression (expression (variable_identifier)) (expression (variable_identifier))))))

=================================================
Function Declarations With Record Wild Cards
=================================================

data Blob = Blob { start :: Int, end :: Int }

f Blob{..} = [start, end]

---

(module
  (algebraic_datatype_declaration
    (type_constructor_identifier)
    (constructors
      (record_data_constructor
        (constructor_identifier)
        (fields
          (field (variable_identifier) (annotation) (type_constructor_identifier))
          (field (variable_identifier) (annotation) (type_constructor_identifier))))))
  (function_declaration
    (variable_identifier)
    (labeled_pattern
      (constructor_identifier)
      (record_wild_cards))
    (function_body (list_expression (expression (variable_identifier)) (expression (variable_identifier))))))

=================================================
Function Declarations With Field Patterns, Named Field Puns, And Record Wild Cards
=================================================

data Blob = Blob { start :: Int, end :: Int, name :: String, path :: String }

f Blob{start, end = end', ..} = [start, end', name, path]

---

(module
  (algebraic_datatype_declaration
    (type_constructor_identifier)
    (constructors
      (record_data_constructor
        (constructor_identifier)
        (fields
          (field (variable_identifier) (annotation) (type_constructor_identifier))
          (field (variable_identifier) (annotation) (type_constructor_identifier))
          (field (variable_identifier) (annotation) (type_constructor_identifier))
          (field (variable_identifier) (annotation) (type_constructor_identifier))))))
  (function_declaration
    (variable_identifier)
    (labeled_pattern
      (constructor_identifier)
      (named_field_pun (variable_identifier))
      (field_pattern (variable_identifier) (variable_identifier))
      (record_wild_cards))
    (function_body (list_expression (expression (variable_identifier)) (expression (variable_identifier)) (expression (variable_identifier)) (expression (variable_identifier))))))


=================================================
Function Declarations With Field Labels And @
=================================================

f c@Ex { a = 1 } = c

---

 (module
  (function_declaration
    (variable_identifier)
    (as_pattern
      (variable_identifier)
      (labeled_pattern (constructor_identifier)
      (field_pattern
        (variable_identifier)
        (integer))))
  (function_body (variable_identifier))))

=================================================
Function Declarations With Parenthesized Pattern
=================================================

f (1) = 1
f (-(1)) = 1
f (Example a b c) = a
f (a :<: f) = 2
f ([]) = 1

---

(module
  (function_declaration
    (variable_identifier)
    (parenthesized_pattern (integer))
    (function_body (integer)))
  (function_declaration
    (variable_identifier)
    (parenthesized_pattern (negative_literal (integer)))
    (function_body (integer)))
  (function_declaration
    (variable_identifier)
    (parenthesized_pattern
      (constructor_pattern
        (constructor_identifier)
        (variable_identifier)
        (variable_identifier)
        (variable_identifier)))
    (function_body (variable_identifier)))
  (function_declaration
    (variable_identifier)
    (parenthesized_pattern
      (variable_identifier)
      (constructor_operator (constructor_symbol))
      (variable_identifier))
    (function_body (integer)))
  (function_declaration
    (variable_identifier)
    (parenthesized_pattern (list_constructor))
    (function_body (integer))))

=================================================
Function Declarations With Tuples
=================================================

f (1, 2) = 1
f ((Just 1), Just 2) = Just 1
f (Just a, Nothing) = Nothing
f (Left a, Right b, -(1)) = b

---

(module
  (function_declaration
    (variable_identifier)
    (tuple_pattern
      (pattern (integer))
      (pattern (integer)))
    (function_body (integer)))
  (function_declaration
    (variable_identifier)
    (tuple_pattern
      (pattern (parenthesized_pattern (constructor_pattern (constructor_identifier) (integer))))
      (pattern (constructor_pattern (constructor_identifier) (integer))))
    (function_body
      (function_application
        (constructor_identifier)
        (integer))))
  (function_declaration
    (variable_identifier)
    (tuple_pattern
      (pattern (constructor_pattern (constructor_identifier) (variable_identifier)))
      (pattern (constructor_identifier)))
    (function_body (constructor_identifier)))
  (function_declaration
    (variable_identifier)
    (tuple_pattern
      (pattern (constructor_pattern (constructor_identifier) (variable_identifier)))
      (pattern (constructor_pattern (constructor_identifier) (variable_identifier)))
      (pattern (negative_literal (integer))))
    (function_body (variable_identifier))))

=================================================
Function Declarations With Lists
=================================================

f [] = 0
f [a] = a
f (a:bs) = a
f (a:b:cs) = a
f (a:b:c:ds) = a

---

(module
  (function_declaration
    (variable_identifier)
    (list_constructor)
    (function_body (integer)))
  (function_declaration
    (variable_identifier)
    (list_pattern (pattern (variable_identifier)))
    (function_body (variable_identifier)))
  (function_declaration
    (variable_identifier)
    (parenthesized_pattern
      (variable_identifier)
      (constructor_operator (constructor_symbol))
      (variable_identifier))
    (function_body (variable_identifier)))
  (function_declaration
    (variable_identifier)
    (parenthesized_pattern
      (variable_identifier)
      (constructor_operator (constructor_symbol))
      (variable_identifier)
      (constructor_operator (constructor_symbol))
      (variable_identifier))
    (function_body (variable_identifier)))
  (function_declaration
    (variable_identifier)
    (parenthesized_pattern
      (variable_identifier)
      (constructor_operator (constructor_symbol))
      (variable_identifier)
      (constructor_operator (constructor_symbol))
      (variable_identifier)
      (constructor_operator (constructor_symbol))
      (variable_identifier))
    (function_body (variable_identifier))))

=================================================
Function Declarations With Irrefutable Pattern
=================================================

f ~a = 1
f ~(-(1)) = 1
f ~(~(a, b), c) = c

---

(module
  (function_declaration
    (variable_identifier)
    (irrefutable_pattern (variable_identifier))
    (function_body (integer)))
  (function_declaration
    (variable_identifier)
    (irrefutable_pattern (parenthesized_pattern (negative_literal (integer))))
    (function_body (integer)))
  (function_declaration
    (variable_identifier)
    (irrefutable_pattern
      (tuple_pattern
        (pattern
          (irrefutable_pattern
            (tuple_pattern
              (pattern (variable_identifier))
              (pattern (variable_identifier)))))
        (pattern (variable_identifier))))
    (function_body (variable_identifier))))

=================================================
Function Declarations With Where
=================================================

f a = c where c = d
f a = c
  where
    c = d
    d = 1


---

(module
  (function_declaration
    (variable_identifier)
    (variable_identifier)
    (function_body
      (variable_identifier)
      (where
        (function_declaration
          (variable_identifier)
          (function_body (variable_identifier))))))
  (function_declaration
    (variable_identifier)
    (variable_identifier)
    (function_body (variable_identifier)
    (where
      (function_declaration
        (variable_identifier)
        (function_body (variable_identifier)))
      (function_declaration
        (variable_identifier)
        (function_body (integer)))))))

=================================================
Function Declarations With Let
=================================================

f = let y = x
        x = 1
      in y

f = let y = g; g = 1 in y

f = let y = x
        x :: Int
        x = 1 in y

f = let { y :: Int;
          y = x;
          x :: Int;
          x = 1; } in y

---

(module
  (function_declaration
    (variable_identifier)
    (function_body
      (let_expression
        (function_declaration
          (variable_identifier)
          (function_body (variable_identifier)))
        (function_declaration
          (variable_identifier)
          (function_body (integer)))
      (in_clause (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (let_expression
      (function_declaration
        (variable_identifier)
        (function_body (variable_identifier)))
      (function_declaration
        (variable_identifier)
        (function_body (integer)))
      (in_clause (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (let_expression
        (function_declaration
          (variable_identifier)
          (function_body (variable_identifier)))
        (type_signature
          (variable_identifier)
          (annotation)
          (type_constructor_identifier))
        (function_declaration
          (variable_identifier)
          (function_body (integer)))
    (in_clause (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (let_expression
        (type_signature
          (variable_identifier)
          (annotation)
          (type_constructor_identifier))
        (function_declaration
          (variable_identifier)
          (function_body (variable_identifier)))
        (type_signature
          (variable_identifier)
          (annotation)
          (type_constructor_identifier))
        (function_declaration
          (variable_identifier)
          (function_body (integer)))
      (in_clause (variable_identifier))))))

=================================================
Function Declarations With Case
=================================================

f x = case x of
  Just a | a < 10 -> True
         | a < 20 -> False
         | a > 19 -> True

g x = case x of
  Just a | a < 10, True, let b :: Int -> Int
                             b x = x -> True
  Nothing -> False

f x = case x of
  Just _ -> x where x = True
  Nothing -> False

f a = case a of
  Just a -> g
    where g = h
          h = 1
  Nothing -> i
    where i = j
          j = 2

f a = case a of
  Just a -> g
  Nothing -> i
  where g = 1
        i = 2

f = (
    \ a ->
      case a of
        A -> b
        )

---

(module
  (function_declaration
    (variable_identifier)
    (variable_identifier)
    (function_body
      (case_expression
        (variable_identifier)
        (alternative
          (constructor_pattern
            (constructor_identifier)
            (variable_identifier))
          (case_guard_pattern
            (guard
              (infix_operator_application
                (variable_identifier)
                (variable_operator
                  (variable_symbol))
                (integer)))
            (constructor_identifier))
          (case_guard_pattern
            (guard
              (infix_operator_application
                (variable_identifier)
                (variable_operator
                  (variable_symbol))
                (integer)))
            (constructor_identifier))
          (case_guard_pattern
            (guard
              (infix_operator_application
                (variable_identifier)
                (variable_operator
                  (variable_symbol))
                (integer)))
            (constructor_identifier))))))
  (function_declaration
    (variable_identifier)
    (variable_identifier)
    (function_body
      (case_expression (variable_identifier)
        (alternative
          (constructor_pattern (constructor_identifier) (variable_identifier))
          (case_guard_pattern
            (guard
              (infix_operator_application
                (variable_identifier) (variable_operator (variable_symbol)) (integer)))
            (guard
              (constructor_identifier))
            (guard
              (let_statement
                (type_signature
                  (variable_identifier)
                  (annotation)
                  (function_type
                    (type (type_constructor_identifier))
                    (type (type_constructor_identifier))))
                  (function_declaration
                    (variable_identifier)
                    (variable_identifier)
                    (function_body (variable_identifier)))))
            (constructor_identifier)))
        (alternative
          (constructor_identifier) (constructor_identifier)))))
  (function_declaration
    (variable_identifier)
    (variable_identifier)
    (function_body
      (case_expression
        (variable_identifier)
        (alternative
          (constructor_pattern (constructor_identifier) (wildcard))
          (variable_identifier) (where (function_declaration (variable_identifier) (function_body (constructor_identifier)))))
        (alternative
          (constructor_identifier)
          (constructor_identifier)))))
  (function_declaration
    (variable_identifier)
    (variable_identifier)
    (function_body
      (case_expression
        (variable_identifier)
        (alternative
          (constructor_pattern (constructor_identifier) (variable_identifier))
          (variable_identifier)
          (where
            (function_declaration (variable_identifier) (function_body (variable_identifier)))
            (function_declaration (variable_identifier) (function_body (integer)))))
        (alternative
          (constructor_identifier) (variable_identifier)
          (where
            (function_declaration (variable_identifier) (function_body (variable_identifier)))
            (function_declaration (variable_identifier) (function_body (integer))))))))
  (function_declaration
    (variable_identifier)
    (variable_identifier)
    (function_body
      (case_expression
        (variable_identifier)
        (alternative
          (constructor_pattern (constructor_identifier) (variable_identifier)) (variable_identifier))
        (alternative
          (constructor_identifier) (variable_identifier))
        (where
          (function_declaration (variable_identifier) (function_body (integer)))
          (function_declaration (variable_identifier) (function_body (integer)))))))
  (function_declaration
    (variable_identifier)
    (function_body
      (parenthesized_expression
        (lambda
          (lambda_head
            (variable_identifier))
          (lambda_body
            (case_expression
              (variable_identifier)
              (alternative
                (constructor_identifier)
                (variable_identifier)))))))))

=================================================
Function Declarations With LambdaCase
=================================================


a = reify tcName >>= \case
      TyConI (DataD _ _ _ _ cons _) -> do
        sigs <- filter (const makeSigs) <$> traverse genSig cons
        decs <- traverse genDecl cons
        pure $ sigs ++ decs

      _ ->
        fail "makeEff expects a type constructor"

---

(module
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (function_application
          (variable_identifier)
          (variable_identifier))
        (variable_operator (variable_symbol))
        (lambda_case
          (alternative
            (constructor_pattern
              (constructor_identifier)
              (parenthesized_pattern
                (constructor_pattern
                  (constructor_identifier)
                  (wildcard)
                  (wildcard)
                  (wildcard)
                  (wildcard)
                  (variable_identifier)
                  (wildcard))))
            (do
              (bind_pattern
                (variable_identifier)
                (infix_operator_application
                  (function_application
                    (variable_identifier)
                    (parenthesized_expression
                      (function_application (variable_identifier) (variable_identifier))))
                  (variable_operator (variable_symbol))
                  (function_application
                    (function_application
                      (variable_identifier)
                      (variable_identifier))
                    (variable_identifier))))
              (bind_pattern
                (variable_identifier)
                (function_application
                  (function_application
                    (variable_identifier)
                    (variable_identifier))
                  (variable_identifier)))
              (infix_operator_application
                (variable_identifier)
                (variable_operator (variable_symbol))
                (infix_operator_application
                  (variable_identifier)
                  (variable_operator (variable_symbol))
                  (variable_identifier)))))
          (alternative
            (wildcard)
            (function_application (variable_identifier) (string))))))))

=================================================
Function Declarations With Guards
=================================================

f x | x < 10, x > 2 = True
    | Foo (Bar Baz{..} _) : woo <- fizz = True
    | otherwise = False

---

(module
  (function_declaration
    (variable_identifier)
    (variable_identifier)
    (function_body
      (function_guard_pattern
        (guard
          (infix_operator_application (variable_identifier) (variable_operator (variable_symbol)) (integer)))
        (guard
          (infix_operator_application (variable_identifier) (variable_operator (variable_symbol)) (integer)))
        (constructor_identifier))
      (function_guard_pattern
        (guard
          (pattern_guard
            (pattern
              (constructor_pattern
                (constructor_identifier)
                (parenthesized_pattern
                  (constructor_pattern
                    (constructor_identifier)
                    (labeled_pattern (constructor_identifier) (record_wild_cards)) (wildcard))))
                  (constructor_operator (constructor_symbol))
                  (variable_identifier))
            (expression
              (variable_identifier))))
        (constructor_identifier))
      (function_guard_pattern
        (guard (variable_identifier))
        (constructor_identifier)))))

=================================================
Function Declarations With Do
=================================================

f x = do
  let z = x
  y <- a
  pure y

---

(module
  (function_declaration
    (variable_identifier)
    (variable_identifier)
    (function_body
      (do
        (let_statement
          (function_declaration
            (variable_identifier)
            (function_body (variable_identifier))))
        (bind_pattern
          (variable_identifier)
          (variable_identifier))
        (function_application (variable_identifier) (variable_identifier))))))

=================================================
Function Declarations With Do And Where
=================================================

f x = do
  let z = x
  a
  y
  where y = pure a
        a = 1

---

(module
  (function_declaration
    (variable_identifier)
    (variable_identifier)
    (function_body
      (do
        (let_statement
          (function_declaration
            (variable_identifier)
            (function_body (variable_identifier))))
        (variable_identifier)
        (variable_identifier)
        (where
          (function_declaration
            (variable_identifier)
            (function_body
              (function_application
                (variable_identifier)
                (variable_identifier))))
          (function_declaration
            (variable_identifier)
            (function_body
              (integer))))))))

=================================================
Function Declarations With i
=================================================

f = a i

---

(module
  (function_declaration
    (variable_identifier)
    (function_body
      (function_application
        (variable_identifier)
        (variable_identifier)))))

=================================================
Function Declarations With Field Update
=================================================

f y@Example = y { a = 1, b = 2 }
f y@(Example { a = a', b = b' }) = y { a = a' + 1, b = b' ++ " !" }

---

(module
  (function_declaration
    (variable_identifier)
    (as_pattern (variable_identifier) (constructor_identifier))
    (function_body
      (labeled_update
        (variable_identifier)
        (field_bind (variable_identifier) (integer))
        (field_bind (variable_identifier) (integer)))))
  (function_declaration
    (variable_identifier)
    (as_pattern
      (variable_identifier)
      (parenthesized_pattern
        (labeled_pattern
          (constructor_identifier)
          (field_pattern (variable_identifier) (variable_identifier))
          (field_pattern (variable_identifier) (variable_identifier)))))
    (function_body
      (labeled_update
        (variable_identifier)
        (field_bind
          (variable_identifier)
          (infix_operator_application
            (variable_identifier)
            (variable_operator (variable_symbol))
            (integer)))
        (field_bind
          (variable_identifier)
          (infix_operator_application
            (variable_identifier)
            (variable_operator (variable_symbol))
            (string)))))))


=================================================
Function Declarations With Type Applications
=================================================

f = read @Int
f = read @Int "5"
f = read @Prelude.Int "5"
f = read @Int . Prelude.id
f = read @Prelude.Int . Prelude.id
f = read @Int . id
f = read @Prelude.Int . Prelude.id
f = read @Int .id
f = read @Prelude.Int .Prelude.id
f = read @Int. id
f = read @Prelude.Int. Prelude.id
f = read @(x (Bar a))

---

(module
  (function_declaration
    (variable_identifier)
    (function_body
      (variable_identifier)
      (type_application (constructor_identifier))))
  (function_declaration
    (variable_identifier)
    (function_body
      (function_application
        (variable_identifier)
        (type_application (constructor_identifier))
        (string))))
  (function_declaration
    (variable_identifier)
    (function_body
      (function_application
        (variable_identifier)
        (type_application (qualified_constructor_identifier (module_identifier) (constructor_identifier)))
        (string))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (variable_identifier)
        (type_application (constructor_identifier))
        (variable_operator (variable_symbol))
        (qualified_variable_identifier (module_identifier) (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (variable_identifier)
        (type_application (qualified_constructor_identifier (module_identifier) (constructor_identifier)))
        (variable_operator (variable_symbol))
        (qualified_variable_identifier (module_identifier) (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (variable_identifier)
        (type_application (constructor_identifier))
        (variable_operator (variable_symbol))
        (variable_identifier))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (variable_identifier)
        (type_application (qualified_constructor_identifier (module_identifier) (constructor_identifier)))
        (variable_operator (variable_symbol))
        (qualified_variable_identifier (module_identifier) (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (variable_identifier)
        (type_application (constructor_identifier))
        (variable_operator (variable_symbol))
        (variable_identifier))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (variable_identifier)
        (type_application (qualified_constructor_identifier (module_identifier) (constructor_identifier)))
        (variable_operator (variable_symbol))
        (qualified_variable_identifier (module_identifier) (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (variable_identifier)
        (type_application (constructor_identifier))
        (variable_operator (variable_symbol))
        (variable_identifier))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (variable_identifier)
        (type_application (qualified_constructor_identifier (module_identifier) (constructor_identifier)))
        (variable_operator (variable_symbol))
        (qualified_variable_identifier (module_identifier) (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (variable_identifier)
      (type_application
        (parenthesized_expression
          (function_application
            (variable_identifier)
            (parenthesized_expression
              (function_application
                (constructor_identifier)
                (variable_identifier)))))))))

=================================================
Function Declarations With Qualified Variable Composition
=================================================

f = Data.List.uncons . id
f = Data.List.uncons . Prelude.id
f = Data.List.uncons. id
f = Data.List.uncons. Prelude.id
f = Data.List.uncons .id
f = Data.List.uncons .Prelude.id
f = Data.List.uncons.id
f = Data.List.uncons.Prelude.id

---

(module
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (qualified_variable_identifier (qualified_module_identifier (module_identifier) (module_identifier)) (variable_identifier))
        (variable_operator (variable_symbol))
        (variable_identifier))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (qualified_variable_identifier
          (qualified_module_identifier (module_identifier) (module_identifier)) (variable_identifier))
          (variable_operator (variable_symbol))
          (qualified_variable_identifier (module_identifier) (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (qualified_variable_identifier (qualified_module_identifier (module_identifier) (module_identifier)) (variable_identifier))
        (variable_operator (variable_symbol))
        (variable_identifier))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (qualified_variable_identifier
          (qualified_module_identifier (module_identifier) (module_identifier)) (variable_identifier))
          (variable_operator (variable_symbol))
          (qualified_variable_identifier (module_identifier) (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (qualified_variable_identifier (qualified_module_identifier (module_identifier) (module_identifier)) (variable_identifier))
        (variable_operator (variable_symbol))
        (variable_identifier))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (qualified_variable_identifier
          (qualified_module_identifier (module_identifier) (module_identifier)) (variable_identifier))
          (variable_operator (variable_symbol))
          (qualified_variable_identifier (module_identifier) (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (qualified_variable_identifier (qualified_module_identifier (module_identifier) (module_identifier)) (variable_identifier))
        (variable_operator (variable_symbol))
        (variable_identifier))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (qualified_variable_identifier
          (qualified_module_identifier (module_identifier) (module_identifier)) (variable_identifier))
          (variable_operator (variable_symbol))
          (qualified_variable_identifier (module_identifier) (variable_identifier))))))

=================================================
Function Declarations With Qualified Constructor Composition
=================================================

f = Data.Maybe.Just . id
f = Data.Maybe.Just . Prelude.id
f = Data.Maybe.Just. id
f = Data.Maybe.Just. Prelude.id
f = Data.Maybe.Just .id
f = Data.Maybe.Just .Prelude.id

---

(module
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (qualified_constructor_identifier (qualified_module_identifier (module_identifier) (module_identifier)) (constructor_identifier))
        (variable_operator (variable_symbol))
        (variable_identifier))))
  (function_declaration
    (variable_identifier)
    (function_body
    (infix_operator_application
      (qualified_constructor_identifier (qualified_module_identifier (module_identifier) (module_identifier)) (constructor_identifier))
      (variable_operator (variable_symbol))
      (qualified_variable_identifier (module_identifier) (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (qualified_constructor_identifier (qualified_module_identifier (module_identifier) (module_identifier)) (constructor_identifier))
        (variable_operator (variable_symbol))
        (variable_identifier))))
  (function_declaration
    (variable_identifier)
    (function_body
    (infix_operator_application
      (qualified_constructor_identifier (qualified_module_identifier (module_identifier) (module_identifier)) (constructor_identifier))
      (variable_operator (variable_symbol))
      (qualified_variable_identifier (module_identifier) (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (qualified_constructor_identifier (qualified_module_identifier (module_identifier) (module_identifier)) (constructor_identifier))
        (variable_operator (variable_symbol))
        (variable_identifier))))
  (function_declaration
    (variable_identifier)
    (function_body
    (infix_operator_application
      (qualified_constructor_identifier (qualified_module_identifier (module_identifier) (module_identifier)) (constructor_identifier))
      (variable_operator (variable_symbol))
      (qualified_variable_identifier (module_identifier) (variable_identifier))))))

=================================================
Function Declarations With Promoted Constructor Operators
=================================================

f = Bar ': Baz
f = Bar ':<: Baz

---

(module
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (constructor_identifier)
        (promoted_type_operator (constructor_operator (constructor_symbol)))
        (constructor_identifier))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (constructor_identifier)
        (promoted_type_operator (constructor_operator (constructor_symbol)))
        (constructor_identifier)))))

=================================================
Function Declarations With Partially Applied Operators
=================================================

f = a <>

---

(module
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (variable_identifier)
        (variable_operator (variable_symbol))))))

=================================================
Function Declarations With Empty Where
=================================================

f = 1 where
g = 2 where

---

(module
  (function_declaration
    (variable_identifier)
    (function_body (integer) (where)))
  (function_declaration
    (variable_identifier)
    (function_body (integer) (where))))

=================================================
Function Declarations With Empty Where, Comments, Pragmas
=================================================

f = a where
  {- comment -}
f = a where
  {-
-}
f = a where
  --
f = a where
  {-# COLUMN 42 #-}

b = 2

---

(module
  (function_declaration
    (variable_identifier)
    (function_body
      (variable_identifier)
      (where
        (comment))))
  (function_declaration
    (variable_identifier)
    (function_body
      (variable_identifier)
      (where
        (comment))))
  (function_declaration
    (variable_identifier)
    (function_body
      (variable_identifier)
      (where
        (comment))))
  (function_declaration
    (variable_identifier)
    (function_body
      (variable_identifier)
      (where
        (pragma))))
  (function_declaration
    (variable_identifier)
    (function_body
      (integer))))

=================================================
Function Declarations With View Patterns
=================================================

eval (a :< b) (fmap subtermValue -> QualifiedName name iden) = bar

---

(module
  (function_declaration
    (variable_identifier)
    (parenthesized_pattern
      (variable_identifier)
      (constructor_operator (constructor_symbol))
      (variable_identifier))
    (view_pattern
      (function_application
        (variable_identifier)
        (variable_identifier))
      (constructor_pattern
        (constructor_identifier)
        (variable_identifier)
        (variable_identifier)))
  (function_body (variable_identifier))))

=================================================
Function Declarations With Implicit Parameters
=================================================

sort :: (?cmp :: a -> a -> Bool) => [a] -> [a]
sort = sortBy ?cmp

---

(module
  (type_signature
    (variable_identifier)
    (annotation)
    (context
      (context_pattern
        (type_signature
          (implicit_parameter_identifier)
          (annotation)
          (function_type
            (type (type_variable_identifier))
            (function_type
              (type (type_variable_identifier))
              (type (type_constructor_identifier)))))))
    (function_type
      (type (list_type (type (type_variable_identifier))))
      (type (list_type (type (type_variable_identifier))))))
  (function_declaration
    (variable_identifier)
    (function_body
      (function_application
        (variable_identifier)
        (implicit_parameter_identifier)))))

=================================================
Function Declarations With Annotated Type Variables
=================================================

b (E (u :: Union e b) q) = a

---

(module
  (function_declaration
    (variable_identifier)
    (parenthesized_pattern
      (constructor_pattern
        (constructor_identifier)
        (annotated_type_variable
          (type_variable_identifier)
          (annotation)
          (constructor_pattern
            (constructor_identifier)
            (variable_identifier)
            (variable_identifier)))
        (variable_identifier)))
    (function_body (variable_identifier))))

=================================================
Function Declarations With Equality Constraints
=================================================

ifte :: ( IvoryStore a
        , IvoryZero ('Stored a)
        , GetAlloc eff ~ 'Scope s
        ) => IBool
          -> Ivory eff a
          -> Ivory eff a
          -> Ivory eff a

---

(module
  (type_signature
    (variable_identifier)
    (annotation)
    (context
      (context_pattern
        (class
          (type_class_identifier)
          (type_variable_identifier)))
      (context_pattern
        (class
          (type_class_identifier)
          (parenthesized_type_pattern
          (quoted_name (type_constructor_identifier))
          (type_variable_identifier))))
      (context_pattern
        (equality_constraint
          (equality_lhs
            (class
              (type_class_identifier)
              (type_variable_identifier)))
          (equality_rhs
            (class
              (quoted_name (type_constructor_identifier))
              (type_variable_identifier))))))
    (function_type
      (type (type_constructor_identifier))
      (function_type
        (type
          (type_constructor_identifier) (type_variable_identifier) (type_variable_identifier))
        (function_type
          (type (type_constructor_identifier) (type_variable_identifier) (type_variable_identifier))
          (type (type_constructor_identifier) (type_variable_identifier) (type_variable_identifier)))))))
