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
let
The type of e1 is τ1
Under a typing environment, where the type of x is τ1, the type of e2 is τ2.
let
let
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 rec
Under 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 rec
A 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_typ
Dereferencing 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 t
Checks 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 t2
unify t1 t2
unify 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 e
g 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.