===============================
Function Application
===============================

module A where
f = a b
f = a b c
f = a b c d

---

(module
  (module_identifier)
  (where
    (function_declaration
      (variable_identifier)
      (function_body
        (function_application
          (variable_identifier)
          (variable_identifier))))
    (function_declaration
      (variable_identifier)
      (function_body
        (function_application
          (function_application
            (variable_identifier)
            (variable_identifier))
          (variable_identifier))))
    (function_declaration
      (variable_identifier)
      (function_body
        (function_application
          (function_application
            (function_application
              (variable_identifier)
              (variable_identifier))
            (variable_identifier))
          (variable_identifier))))))

===============================
Function Application With Constructors
===============================

module A where
f = Just b
f = Right b
f = Example a c d
f = ()

---

(module
  (module_identifier)
    (where
      (function_declaration
        (variable_identifier)
        (function_body
          (function_application
            (constructor_identifier) (variable_identifier))))
      (function_declaration
        (variable_identifier)
        (function_body
          (function_application
            (constructor_identifier)
            (variable_identifier))))
      (function_declaration
        (variable_identifier)
        (function_body
          (function_application
            (function_application
              (function_application
                (constructor_identifier)
                (variable_identifier))
              (variable_identifier))
            (variable_identifier))))
      (function_declaration
        (variable_identifier)
        (function_body
          (unit_constructor)))))

===============================
Function Application With List Comprehensions
===============================

module A where
f = take 5 [ [ (i,j) | i <- [1,2] ] | j <- [1..] ]

---

(module
  (module_identifier)
  (where
    (function_declaration
      (variable_identifier)
      (function_body
        (function_application
          (function_application
            (variable_identifier)
            (integer))
          (list_comprehension
            (list_comprehension
              (tuple_expression (expression (variable_identifier)) (expression (variable_identifier)))
              (generator (variable_identifier) (list_expression (expression (integer)) (expression (integer)))))
              (generator (variable_identifier) (arithmetic_sequence (enum_from (integer))))))))))

===============================
Arithmetic Sequence
===============================

module A where
a = [1..]
a = [1,2..]
a = [1..2]
a = [1,2..10]

---

(module
  (module_identifier)
  (where
    (function_declaration
      (variable_identifier)
      (function_body
        (arithmetic_sequence (enum_from (integer)))))
    (function_declaration
      (variable_identifier)
      (function_body
        (arithmetic_sequence (enum_from_then (integer) (integer)))))
    (function_declaration
      (variable_identifier)
      (function_body
        (arithmetic_sequence (enum_from_to (integer) (integer)))))
    (function_declaration
      (variable_identifier)
      (function_body
        (arithmetic_sequence (enum_from_then_to (integer) (integer) (integer)))))))

===============================
List Comprehensions
===============================

module A where
a = [x | x <- xs]
a = [(x, y) | x <- xs, y <- ys]
a = [ x |  xs   <- [ [(1,2),(3,4)], [(5,4),(3,2)] ], (3,x) <- xs ]
a = [(i,j) | i <- [1,2],
             j <- [1..4] ]
a = [ [ (i,j) | i <- [1,2] ] | j <- [1..] ]

---

(module
  (module_identifier)
  (where
    (function_declaration
      (variable_identifier)
      (function_body
        (list_comprehension
          (variable_identifier)
          (generator (variable_identifier) (variable_identifier)))))
    (function_declaration
      (variable_identifier)
      (function_body
        (list_comprehension
          (tuple_expression (expression (variable_identifier)) (expression (variable_identifier)))
          (generator (variable_identifier) (variable_identifier))
          (generator (variable_identifier) (variable_identifier)))))
    (function_declaration
      (variable_identifier)
      (function_body
        (list_comprehension
          (variable_identifier)
          (generator
            (variable_identifier)
            (list_expression
              (expression
                (list_expression
                  (expression
                    (tuple_expression
                      (expression (integer))
                      (expression (integer))))
                  (expression
                    (tuple_expression (expression (integer)) (expression (integer))))))
              (expression
                (list_expression
                  (expression
                    (tuple_expression
                      (expression (integer))
                      (expression (integer))))
                  (expression
                    (tuple_expression
                      (expression (integer))
                      (expression (integer))))))))
          (generator
            (tuple_pattern
              (pattern (integer))
              (pattern (variable_identifier)))
            (variable_identifier)))))
    (function_declaration
      (variable_identifier)
      (function_body
        (list_comprehension
          (tuple_expression (expression (variable_identifier)) (expression (variable_identifier)))
          (generator (variable_identifier) (list_expression (expression (integer)) (expression (integer))))
          (generator (variable_identifier) (arithmetic_sequence (enum_from_to (integer) (integer)))))))
    (function_declaration
      (variable_identifier)
      (function_body
        (list_comprehension (list_comprehension (tuple_expression (expression (variable_identifier)) (expression (variable_identifier))) (generator (variable_identifier) (list_expression (expression (integer)) (expression (integer))))) (generator (variable_identifier) (arithmetic_sequence (enum_from (integer)))))))))

===============================
Right Operator Sections
===============================

module A where
a = (: a)
a = (:< a)

---

(module
  (module_identifier)
  (where
    (function_declaration
      (variable_identifier)
      (function_body (right_operator_section (constructor_operator (constructor_symbol)) (variable_identifier))))
    (function_declaration
      (variable_identifier)
      (function_body (right_operator_section (constructor_operator (constructor_symbol)) (variable_identifier))))))

===============================
Left Operator Sections
===============================

module A where
a = (a :)
a = (a :|)

---

(module
  (module_identifier)
  (where
    (function_declaration
      (variable_identifier)
      (function_body
        (left_operator_section (variable_identifier) (constructor_operator (constructor_symbol)))))
    (function_declaration
      (variable_identifier)
      (function_body
        (left_operator_section (variable_identifier) (constructor_operator (constructor_symbol)))))))

===============================
Infix Operator Applications
===============================

module A where
parseJSON (JSON.Object r) = IncPK <$>
  r .: "id" <*>
  r .: "nullable_string" <*>
  r .: "non_nullable_string" <*>
  r .: "inserted_at"

f = do
  a <- b =<< c
  b <- e >>= g

g = h `i` j

k = l `M.n` o

h = a <|> b

i = a - b

---

(module
  (module_identifier)
  (where
    (function_declaration
      (variable_identifier)
      (parenthesized_pattern (constructor_pattern (qualified_constructor_identifier (module_identifier) (constructor_identifier)) (variable_identifier)))
      (function_body
        (infix_operator_application
          (constructor_identifier)
          (variable_operator (variable_symbol))
          (infix_operator_application
            (variable_identifier)
            (variable_operator (variable_symbol))
            (infix_operator_application
              (string)
              (variable_operator (variable_symbol))
              (infix_operator_application
                (variable_identifier)
                (variable_operator (variable_symbol))
                (infix_operator_application
                  (string)
                  (variable_operator (variable_symbol))
                  (infix_operator_application
                    (variable_identifier)
                    (variable_operator (variable_symbol))
                    (infix_operator_application
                      (string)
                      (variable_operator (variable_symbol))
                      (infix_operator_application
                        (variable_identifier)
                        (variable_operator (variable_symbol))
                        (string)))))))))))

    (function_declaration
      (variable_identifier)
      (function_body
        (do
          (bind_pattern
            (variable_identifier)
            (infix_operator_application
              (variable_identifier)
              (variable_operator (variable_symbol))
              (variable_identifier)))
          (bind_pattern
            (variable_identifier)
            (infix_operator_application
              (variable_identifier)
              (variable_operator (variable_symbol))
              (variable_identifier))))))

    (function_declaration
      (variable_identifier)
      (function_body
        (infix_operator_application
          (variable_identifier)
          (variable_operator (infix_variable_identifier))
          (variable_identifier))))

    (function_declaration
      (variable_identifier)
      (function_body
        (infix_operator_application
          (variable_identifier)
          (variable_operator (qualified_infix_variable_identifier (qualified_variable_identifier (module_identifier) (variable_identifier))))
          (variable_identifier))))

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

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

===============================
Lambda Abstractions
===============================

f = \ x -> x

f = \ (Just a) -> a

f = \ x -> x : a : xs

f = \ g a b -> g <$> a <*> b

---

(module
  (function_declaration
    (variable_identifier)
    (function_body
      (lambda
        (lambda_head
          (variable_identifier))
        (lambda_body
          (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (lambda
        (lambda_head
          (parenthesized_pattern (constructor_pattern (constructor_identifier) (variable_identifier))))
        (lambda_body (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (lambda
        (lambda_head
          (variable_identifier))
        (lambda_body
          (infix_operator_application
            (variable_identifier)
            (constructor_operator (constructor_symbol))
            (infix_operator_application
              (variable_identifier)
              (constructor_operator (constructor_symbol))
              (variable_identifier)))))))
  (function_declaration
    (variable_identifier)
    (function_body
      (lambda
        (lambda_head
          (variable_identifier)
          (variable_identifier)
          (variable_identifier))
        (lambda_body
          (infix_operator_application
            (variable_identifier)
            (variable_operator (variable_symbol))
            (infix_operator_application
              (variable_identifier)
              (variable_operator (variable_symbol))
              (variable_identifier))))))))

===============================
Problematic Variable Symbols
===============================

f = (-)
f = 1 - 1
f = (-1)
f = (-a)
f = -(1)

---

(module
  (function_declaration
    (variable_identifier)
    (function_body (variable_operator (variable_symbol))))
  (function_declaration
    (variable_identifier)
    (function_body
      (infix_operator_application
        (integer)
        (variable_operator (variable_symbol))
        (integer))))
  (function_declaration
    (variable_identifier)
    (function_body
      (parenthesized_expression (prefix_negation (integer)))))
  (function_declaration
    (variable_identifier)
    (function_body
      (parenthesized_expression (prefix_negation (variable_identifier)))))
  (function_declaration
    (variable_identifier)
    (function_body (prefix_negation (parenthesized_expression (integer))))))

===============================
Partial Tuple Expressions
===============================

let foo' = catMaybes $ fmap (\p -> (p,) . Just <$> bar p) waz

---

(module
  (function_declaration
    (variable_identifier)
    (variable_identifier)
    (function_body
      (infix_operator_application
        (variable_identifier)
        (variable_operator (variable_symbol))
        (function_application
          (function_application
            (variable_identifier)
            (parenthesized_expression
              (lambda
                (lambda_head (variable_identifier))
                (lambda_body
                  (infix_operator_application
                    (tuple_expression (expression (variable_identifier)))
                    (variable_operator (variable_symbol))
                    (infix_operator_application
                      (constructor_identifier)
                      (variable_operator (variable_symbol))
                      (function_application
                        (variable_identifier)
                        (variable_identifier))))))))
          (variable_identifier))))))
