На роботі мені було доручено виводити інформацію про тип динамічної мови. Я переписую послідовності висловлювань у вкладені 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.