На роботі мені було доручено виводити інформацію про тип динамічної мови. Я переписую послідовності висловлювань у вкладені letвирази, як-от так:
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 }
Оскільки я починаю з загальної інформації про тип і намагаюся вивести більш конкретні типи, природним вибором є типи уточнення. Наприклад, умовний оператор повертає об'єднання типів його істинних і хибних гілок. У простих випадках це працює дуже добре.
Однак я натрапив на корч, намагаючись зробити такий тип:
function g(f) {
var x;
x = f(3);
return f(x);
}
Який переписаний на:
\f.
let x = undefined in
let x = f 3 in
f x
HM зробить висновок і, отже, . Фактичний тип, який я хочу мати змогу зробити, це:
I’m already using functional dependencies to resolve the type of an overloaded + operator, so I figured it was a natural choice to use them to resolve the type of f within g. That is, the types of f in all its applications together uniquely determine the type of g. However, as it turns out, fundeps don’t lend themselves terribly well to variable numbers of source types.
Anyway, the interplay of polymorphism and refinement typing is problematic. So is there a better approach I’m missing? I’m currently digesting “Refinement Types for ML” and would appreciate more literature or other pointers.