================================================================================
polymorphism.ncl
================================================================================

# First projection, statically typed
let fst : forall a b. a -> b -> a = fun x y => x in
# Evaluation function, statically typed
let ev : forall a b. (a -> b) -> a -> b = fun f x => f x in
let id : forall a. a -> a = fun x => x in
(ev id (fst 5 10) == 5 : Bool)

--------------------------------------------------------------------------------

(term
  (comment)
  (uni_term
    (let_expr
      (let_in_block
        (let_binding
          (pattern
            (ident))
          (annot
            (annot_atom
              (types
                (forall
                  (ident)
                  (ident)
                  (types
                    (infix_expr
                      (infix_expr
                        (applicative
                          (record_operand
                            (atom
                              (ident)))))
                      (infix_expr
                        (infix_expr
                          (applicative
                            (record_operand
                              (atom
                                (ident)))))
                        (infix_expr
                          (applicative
                            (record_operand
                              (atom
                                (ident))))))))))))
          (term
            (uni_term
              (fun_expr
                (pattern_fun
                  (ident))
                (pattern_fun
                  (ident))
                (term
                  (uni_term
                    (infix_expr
                      (applicative
                        (record_operand
                          (atom
                            (ident))))))))))))
      (comment)
      (term
        (uni_term
          (let_expr
            (let_in_block
              (let_binding
                (pattern
                  (ident))
                (annot
                  (annot_atom
                    (types
                      (forall
                        (ident)
                        (ident)
                        (types
                          (infix_expr
                            (infix_expr
                              (applicative
                                (record_operand
                                  (atom
                                    (uni_term
                                      (infix_expr
                                        (infix_expr
                                          (applicative
                                            (record_operand
                                              (atom
                                                (ident)))))
                                        (infix_expr
                                          (applicative
                                            (record_operand
                                              (atom
                                                (ident)))))))))))
                            (infix_expr
                              (infix_expr
                                (applicative
                                  (record_operand
                                    (atom
                                      (ident)))))
                              (infix_expr
                                (applicative
                                  (record_operand
                                    (atom
                                      (ident))))))))))))
                (term
                  (uni_term
                    (fun_expr
                      (pattern_fun
                        (ident))
                      (pattern_fun
                        (ident))
                      (term
                        (uni_term
                          (infix_expr
                            (applicative
                              (applicative
                                (record_operand
                                  (atom
                                    (ident))))
                              (record_operand
                                (atom
                                  (ident))))))))))))
            (term
              (uni_term
                (let_expr
                  (let_in_block
                    (let_binding
                      (pattern
                        (ident))
                      (annot
                        (annot_atom
                          (types
                            (forall
                              (ident)
                              (types
                                (infix_expr
                                  (infix_expr
                                    (applicative
                                      (record_operand
                                        (atom
                                          (ident)))))
                                  (infix_expr
                                    (applicative
                                      (record_operand
                                        (atom
                                          (ident)))))))))))
                      (term
                        (uni_term
                          (fun_expr
                            (pattern_fun
                              (ident))
                            (term
                              (uni_term
                                (infix_expr
                                  (applicative
                                    (record_operand
                                      (atom
                                        (ident))))))))))))
                  (term
                    (uni_term
                      (infix_expr
                        (applicative
                          (record_operand
                            (atom
                              (uni_term
                                (annotated_infix_expr
                                  (infix_expr
                                    (infix_expr
                                      (applicative
                                        (applicative
                                          (applicative
                                            (record_operand
                                              (atom
                                                (ident))))
                                          (record_operand
                                            (atom
                                              (ident))))
                                        (record_operand
                                          (atom
                                            (uni_term
                                              (infix_expr
                                                (applicative
                                                  (applicative
                                                    (applicative
                                                      (record_operand
                                                        (atom
                                                          (ident))))
                                                    (record_operand
                                                      (atom
                                                        (num_literal))))
                                                  (record_operand
                                                    (atom
                                                      (num_literal))))))))))
                                    (infix_b_op_8)
                                    (infix_expr
                                      (applicative
                                        (record_operand
                                          (atom
                                            (num_literal))))))
                                  (annot
                                    (annot_atom
                                      (types
                                        (infix_expr
                                          (applicative
                                            (record_operand
                                              (atom
                                                (type_atom
                                                  (type_builtin))))))))))))))))))))))))))
