// Path: src/main/java/litil/TypeScope.java
// public class TypeScope {
// 
//     private final Map<String, Type> scope;
//     private final TypeScope parent;
// 
//     private TypeScope(TypeScope parent, Map<String, Type> scope) {
//         this.parent = parent;
//         this.scope = scope;
//     }
// 
//     public TypeScope(TypeScope parent) {
//         this(parent, new HashMap<String, Type>());
//     }
// 
//     public TypeScope() {
//         this(null, new HashMap<String, Type>());
//     }
// 
//     public void define(String name, Type type) {
//         scope.put(name, type);
//     }
// 
//     public Type get(String name) {
//         Type res = scope.get(name);
//         if (res == null && parent != null) {
//             res = parent.get(name);
//         }
//         return res;
//     }
// 
//     public TypeScope child() {
//         return new TypeScope(this);
//     }
// 
//     @Override
//     public String toString() {
//         return scope + (parent == null ? "-|" : "->" + parent);
//     }
// }


import litil.TypeScope;
import litil.ast.*;
import java.util.ArrayList;
import java.util.List;
                        "'");
            }
            return res;
        } else if (node instanceof Expr.EAp) {
            Expr.EAp ap = (Expr.EAp) node;
            Type funcType = analyze(ap.fn, scope);
            Type argType = analyze(ap.arg, scope);

            Type.Variable resType = new Type.Variable();
            unify(Type.Function(argType, resType), funcType);
            return resType;
        } else if (node instanceof Expr.EIf) {
            Expr.EIf eif = (Expr.EIf) node;
            Type condType = analyze(eif.cond, scope);
            unify(condType, Type.BOOL);

            Type thenType = null;
            for (Instruction instr : eif.thenInstructions) {
                thenType = analyze(instr, scope);
            }

            Type elseType = null;
            for (Instruction instr : eif.elseInstructions) {
                elseType = analyze(instr, scope);
            }

            unify(thenType, elseType);
            return thenType;
        } else if (node instanceof LetBinding) {
            LetBinding let = (LetBinding) node;
// Path: src/main/java/litil/TypeScope.java
// public class TypeScope {
// 
//     private final Map<String, Type> scope;
//     private final TypeScope parent;
// 
//     private TypeScope(TypeScope parent, Map<String, Type> scope) {
//         this.parent = parent;
//         this.scope = scope;
//     }
// 
//     public TypeScope(TypeScope parent) {
//         this(parent, new HashMap<String, Type>());
//     }
// 
//     public TypeScope() {
//         this(null, new HashMap<String, Type>());
//     }
// 
//     public void define(String name, Type type) {
//         scope.put(name, type);
//     }
// 
//     public Type get(String name) {
//         Type res = scope.get(name);
//         if (res == null && parent != null) {
//             res = parent.get(name);
//         }
//         return res;
//     }
// 
//     public TypeScope child() {
//         return new TypeScope(this);
//     }
// 
//     @Override
//     public String toString() {
//         return scope + (parent == null ? "-|" : "->" + parent);
//     }
// }


// Path: src/main/java/litil/tc/MonomorphicTypeChecker.java
import litil.TypeScope;
import litil.ast.*;
import java.util.ArrayList;
import java.util.List;

                        "'");
            }
            return res;
        } else if (node instanceof Expr.EAp) {
            Expr.EAp ap = (Expr.EAp) node;
            Type funcType = analyze(ap.fn, scope);
            Type argType = analyze(ap.arg, scope);

            Type.Variable resType = new Type.Variable();
            unify(Type.Function(argType, resType), funcType);
            return resType;
        } else if (node instanceof Expr.EIf) {
            Expr.EIf eif = (Expr.EIf) node;
            Type condType = analyze(eif.cond, scope);
            unify(condType, Type.BOOL);

            Type thenType = null;
            for (Instruction instr : eif.thenInstructions) {
                thenType = analyze(instr, scope);
            }

            Type elseType = null;
            for (Instruction instr : eif.elseInstructions) {
                elseType = analyze(instr, scope);
            }

            unify(thenType, elseType);
            return thenType;
        } else if (node instanceof LetBinding) {
            LetBinding let = (LetBinding) node;
            TypeScope ss = new TypeScope(scope);