Ken Wakita (https://wakita.github.io/fp2017/)
Oct. 19, 2017
let lexbuf outchan l =
...... .......
(..........
(......
(.........
(.........
(.... !.....
(Alpha.f
(KNormal.f
(........
(.......... ........... .)))))))))

τ::=|bool | int | float|FunctionalType(τ1,…,τn,τ)|TupleType(τ1,…,τn)|ArrayType(τ)|α
let
letThe type of e1 is τ1
Under a typing environment, where the type of x is τ1, the type of e2 is τ2.
letlet form binds a name locally. It introduces a varible x whose value is the evaluation results of e1. The scope of x is e2 (x is visible inside e2).
let x = 1 in x * 2Γ,x:int⊢x:int because Γ,x:int(x)=int.
Γ,x:int⊢2:int because 2 is an integer constant.
Γ,x:int⊢x * 2:int because *:int×int→int.
Γ⊢1:int because 1 is an integer constant.
Γ⊢let x = 1 in x * 2:int, from the last two statements and the typing rule for let.
let rec
let recUnder a typing environment where x is a function whose type is τ1→…τn→τ and the types of y1,…,yn are τ1,…,τn, respectively, the type of e1 is τ. (When the types of virtual and real arguments match the function’s result type and body’s type should be the same.)
Under a typing environment where x is a function whose type is τ1→…τn→τ, the type of e2 is τ′.

let recA function e takes n arguments and their types are τ1,…τn.
The types of e1,…en are τ1,…,τn, respectively.
These two assumption demand that the types of the formal argument and the actual arguments match.
Typing.deref_...A series of function that replaces occurrences of type variable by its contents
Typing.deref_typDereferencing of type variables for Type.t. The essencial code is:
let rec deref_typ = function
...
| Type.Var({ contents = Some(t) } as r) ->
let t' = deref_typ t in
r := Some(t');
t'
...Other code recursively applies deref_* to the subcomponents.
occur r tChecks if a type varible r occurs in a type expression t.
| Type.Var(r2) when r1 == r2 -> true
| Type.Var({ contents = None }) -> false
| Type.Var({ contents = Some(t2) }) -> occur r1 t2unify t1 t2unify t1 t2 attempts unification on type variables to t1 and t2. Instead of computing substitution, type variables are replaced by substitution. This is one of rare cases of using side effects throughout implementation of the MinCaml compiler.
| Type.Var({ contents = None } as r1), _ -> (* t1 is an undefined type variable *)
if occur r1 t2 then raise (Unify(t1, t2));
r1 := Some(t2)
| _, Type.Var({ contents = None } as r2) -> (* t2 is an undefined type variable *)
if occur r2 t1 then raise (Unify(t1, t2));
r2 := Some(t1)The structure of the unify function reflects the typing structure, namely Type.t.
If it fails to unify t1 and t2, it raises an exception: raise (Unify(t1, t2)).
g env eg env e examine the structure of e, identifies the typing rule related with that structure, then attempts to unify the assumptions and conclusions of the typing rule with the corresponding structure of e’s type.