Au travail, j'ai été chargé de déduire des informations de type sur un langage dynamique. Je réécris des séquences d'instructions en imbriquéeslet
expressions , comme ceci:
return x; Z => x
var x; Z => let x = undefined in Z
x = y; Z => let x = y in Z
if x then T else F; Z => if x then { T; Z } else { F; Z }
Étant donné que je pars d'informations générales sur les types et que j'essaye d'en déduire des types plus spécifiques, le choix naturel est les types de raffinement. Par exemple, l'opérateur conditionnel renvoie une union des types de ses branches vraie et fausse. Dans les cas simples, cela fonctionne très bien.
Cependant, j'ai rencontré un problème lorsque j'essayais de déduire le type de ce qui suit:
function g(f) {
var x;
x = f(3);
return f(x);
}
Qui est réécrit pour:
\f.
let x = undefined in
let x = f 3 in
f x
J'utilise déjà des dépendances fonctionnelles pour résoudre le type d'un +
opérateur surchargé , j'ai donc pensé que c'était un choix naturel de les utiliser pour résoudre le type de l' f
intérieur g
. Autrement dit, les types de f
dans toutes ses applications déterminent ensemble le type de g
. Cependant, il s'avère que les fonds ne se prêtent pas très bien à un nombre variable de types de sources.
Quoi qu'il en soit, l'interaction du polymorphisme et du typage de raffinement est problématique. Alors, y a-t-il une meilleure approche qui me manque? Je digère actuellement les «types de raffinement pour ML» et j'apprécierais plus de littérature ou d'autres pointeurs.