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 theny else. Como sabemos 1y 2somos números, por sustitución, sabemos que el ifenunciado 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 ida 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 xes diferente en cada uso de id. La segunda ides una función de tipo a -> a, donde apuede 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, idse pueden sustituir copias nuevas y separadas del tipo de en las restricciones para cada lugar id, por ejemplo a2 -> a2y 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.