============================================
Plain
============================================

let a = 5
let b = a
let c = #foo
export d = 5

---

(source_file
  (let_binding (value_identifier) (number))
  (let_binding (value_identifier) (value_identifier))
  (let_binding (value_identifier) (polyvar (polyvar_identifier)))
  (let_binding (value_identifier) (number)))

============================================
Tuple destructuring
============================================

let (a, b, (c, d)) = foo
let (state: int, setState) = foo

---

(source_file
  (let_binding
    (tuple_pattern
      (tuple_item_pattern (value_identifier))
      (tuple_item_pattern (value_identifier))
      (tuple_item_pattern
        (tuple_pattern
          (tuple_item_pattern (value_identifier))
          (tuple_item_pattern (value_identifier)))))
    (value_identifier))
  (let_binding
    (tuple_pattern
       (tuple_item_pattern (value_identifier) (type_annotation (type_identifier)))
       (tuple_item_pattern (value_identifier)))
    (value_identifier)))

============================================
Block
============================================

let x = {
  3
  4
}

---

(source_file
  (let_binding
    (value_identifier)
    (block
      (expression_statement (number))
      (expression_statement (number)))))

============================================
Annotated
============================================

let a: int = 5
let b: 'a => unit = ignore

---

(source_file
  (let_binding
    (value_identifier)
    (type_annotation (type_identifier))
    (number))
  (let_binding
    (value_identifier)
    (type_annotation
      (function_type
        (function_type_parameters (type_identifier))
        (unit_type)))
    (value_identifier)))

============================================
Recursive
============================================

let rec foo = n => foo(n-1)

---

(source_file
  (let_binding
    (value_identifier)
      (function
        (value_identifier)
        (call_expression
          (value_identifier)
          (arguments
            (binary_expression
              (value_identifier)
              (number)))))))

============================================
Unit
============================================

let () = noop

---

(source_file (let_binding (unit) (value_identifier)))

============================================
And (Primitives)
============================================

let a = 5 and b = 4

---

(source_file
  (let_binding
    (value_identifier)
    (number)
    (value_identifier)
    (number)))

============================================
And (Fuctions)
============================================

let rec a = x => x + b(x) and b = y => y - 1

---

(source_file
  (let_binding
    (value_identifier)
    (function
      (value_identifier)
      (binary_expression
        (value_identifier)
        (call_expression
          (value_identifier)
          (arguments
            (value_identifier)))))
    (value_identifier)
    (function
      (value_identifier)
      (binary_expression
        (value_identifier)
        (number)))))

===========================================
Labled function with uncurried
===========================================

let test = (. ~attr) => ()

---

(source_file
  (let_binding
    (value_identifier)
    (function
      (formal_parameters
        (uncurry)
        (labeled_parameter
          (value_identifier)))
      (unit))))
