Es lamentable que mucha de la literatura sobre el tema sea muy densa. Yo también estaba en tus zapatos. Recibí mi primera introducción al tema de Lenguajes de programación: aplicaciones e interpretación.
http://www.plai.org/
Intentaré resumir la idea abstracta seguida de detalles que no encontré inmediatamente obvios. Primero, se puede pensar en la inferencia de tipos para generar y luego resolver restricciones. Para generar restricciones, recorre el árbol de sintaxis y genera una o más restricciones en cada nodo. Por ejemplo, si el nodo es un +
operador, los operandos y los resultados deben ser todos números. Un nodo que aplica una función tiene el mismo tipo que el resultado de la función, y así sucesivamente.
Para un idioma sin let
, puede resolver ciegamente las restricciones anteriores mediante sustitución. Por ejemplo:
(if (= 1 2)
1
2)
aquí, podemos decir que la condición de la instrucción if debe ser booleana, y que el tipo de instrucción if es el mismo que el tipo de sus cláusulas then
y else
. Como sabemos 1
y 2
somos números, por sustitución, sabemos que el if
enunciado es un número.
Donde las cosas se ponen feas, y lo que no pude entender por un tiempo, es lidiar con dejar:
(let ((id (lambda (x) x)))
(id id))
Aquí, nos hemos vinculado id
a una función que devuelve lo que haya pasado, también conocida como función de identidad. El problema es que el tipo de parámetro de la función x
es diferente en cada uso de id
. La segunda id
es una función de tipo a -> a
, donde a
puede haber cualquier cosa. El primero es de tipo (a -> a) -> (a -> a)
. Esto se conoce como polimorfismo let. La clave es resolver las restricciones en un orden particular: primero resuelva las restricciones para la definición de id
. Esto será a -> a
. Luego, id
se pueden sustituir copias nuevas y separadas del tipo de en las restricciones para cada lugar id
, por ejemplo a2 -> a2
y a3 -> a3
.
Eso no se explicó fácilmente en los recursos en línea. Mencionarán el algoritmo W o M, pero no cómo funcionan en términos de resolución de restricciones, o por qué no se burla del polimorfismo let: cada uno de esos algoritmos impone un orden para resolver las restricciones.
Encontré este recurso extremadamente útil para vincular el algoritmo W, M y el concepto general de generación de restricciones y resolución de todos juntos. Es un poco denso, pero mejor que muchos:
http://www.cs.uu.nl/research/techreps/repo/CS-2002/2002-031.pdf
Muchos de los otros artículos también son buenos:
http://people.cs.uu.nl/bastiaan/papers.html
Espero que ayude a aclarar un mundo algo turbio.