En el trabajo, se me ha encomendado la tarea de inferir cierta información sobre un lenguaje dinámico. Reescribo secuencias de declaraciones en let
expresiones anidadas , así:
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 }
Como comienzo a partir de información de tipo general y trato de deducir tipos más específicos, la elección natural son los tipos de refinamiento. Por ejemplo, el operador condicional devuelve una unión de los tipos de sus ramas verdadera y falsa. En casos simples, funciona muy bien.
Sin embargo, me encontré con un inconveniente al intentar inferir el tipo de lo siguiente:
function g(f) {
var x;
x = f(3);
return f(x);
}
Que se reescribe a:
\f.
let x = undefined in
let x = f 3 in
f x
HM y, en consecuencia, . El tipo real que quiero poder inferir es:
Ya estoy usando dependencias funcionales para resolver el tipo de +
operador sobrecargado , así que pensé que era una opción natural usarlos para resolver el tipo de f
dentro g
. Es decir, los tipos de f
en todas sus aplicaciones juntas determinan de forma única el tipo de g
. Sin embargo, como resultado, los fundeps no se prestan terriblemente bien a un número variable de tipos de fuentes.
De todos modos, la interacción del polimorfismo y la tipificación de refinamiento es problemática. Entonces, ¿hay un mejor enfoque que me estoy perdiendo? Actualmente estoy digiriendo "Tipos de refinamiento para ML" y agradecería más literatura u otros consejos.