На работе мне было поручено вывести некоторую информацию о типах динамического языка. Я переписываю последовательности операторов во вложенные 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 бы и, следовательно, , Фактический тип, который я хочу иметь возможность выводить:
Я уже использую функциональные зависимости для решения типа перегруженного +
оператора, поэтому я решил , что это был естественный выбор , чтобы использовать их для решения типа f
внутри g
. То есть, виды f
во всех его приложениях вместе однозначно определяют тип g
. Однако, как выясняется, fundeps не поддается очень хорошо переменное число типов источников.
Во всяком случае, взаимодействие полиморфизма и уточнения типизации является проблематичным. Так есть ли лучший подход, который я пропускаю? В настоящее время я перевариваю «Типы уточнения для ML» и буду признательна за дополнительную литературу или другие советы.
источник