На работе мне было поручено вывести некоторую информацию о типах динамического языка. Я переписываю последовательности операторов во вложенные 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» и буду признательна за дополнительную литературу или другие советы.