1.4 Environnement de typage
L'environnement de typage, nécessaire lors du typage pour les variables libres (comme les
primitives ou les paramètres formels) d'expressions est représenté par une liste d'association (string * quantified_type) list
.
Il est nécessaire de faire une distinction entre les variables d'un type si elles sont
quantifiées (variables liées) ou si elles ne le sont pas (variables libres).
# let
rec
vars_of_type
t
=
let
rec
vars
vl
=
function
Const_type
_
->
vl
|
Var_type
vt
->
(
match
!
vt
with
Unknown
n
->
if
List.mem
n
vl
then
vl
else
n::vl
|
Instanciated
t
->
vars
vl
t
)
|
Pair_type
(t1,
t2)
->
vars
(vars
vl
t1)
t2
|
List_type
t
->
vars
vl
t
|
Fun_type
(t1,
t2)
->
vars
(vars
vl
t1)
t2
in
vars
[]
t
;;
val vars_of_type : ml_type -> int list = <fun>
Pour calculer les variables libres et liées d'un schéma de type,
# let
subtract
l1
l2
=
List.flatten
(List.map
(function
id
->
if
(List.mem
id
l2)
then
[]
else
[
id]
)
l1);;
val subtract : 'a list -> 'a list -> 'a list = <fun>
# let
free_vars_of_type
(bv,
t)
=
subtract
(vars_of_type
t)
bv
and
bound_vars_of_type
(fv,
t)
=
subtract
(vars_of_type
t)
fv
;;
val free_vars_of_type : int list * ml_type -> int list = <fun>
val bound_vars_of_type : int list * ml_type -> int list = <fun>
# let
append
l1
l2
=
l1@
l2;;
val append : 'a list -> 'a list -> 'a list = <fun>
# let
flat
ll
=
List.fold_right
append
ll
[];;
val flat : 'a list list -> 'a list = <fun>
# let
free_vars_of_type_env
l
=
flat
(
List.map
(function
(id,
Forall
(v,
t))
->
free_vars_of_type
(v,
t))
l)
;;
val free_vars_of_type_env : ('a * quantified_type) list -> int list = <fun>
Lors du typage d'un identificateur dans un environnement C
, le vérificateur cherche
dans l'environnement le type quantifié associé à cet identificateur et en retourne une
instance, où les variables quantifiées valent de nouvelles variables (ou inconnues).
# let
type_instance
st
=
match
st
with
Forall(gv,
t)
->
let
unknowns
=
List.map
(function
n
->
n,
new_unknown())
gv
in
let
rec
instance
=
function
Var_type
{contents=
(Unknown
n)}
as
t
->
(try
List.assoc
n
unknowns
with
Not_found
->
t)
|
Var_type
{contents=
(Instanciated
t)}
->
instance
t
|
Const_type
ct
as
t
->
t
|
Pair_type
(t1,
t2)
->
Pair_type
(instance
t1,
instance
t2)
|
List_type
t
->
List_type
(instance
t)
|
Fun_type
(t1,
t2)
->
Fun_type
(instance
t1,
instance
t2)
in
instance
t
;;
val type_instance : quantified_type -> ml_type = <fun>