É uma pena que grande parte da literatura sobre o assunto seja muito densa. Eu também estava no seu lugar. Tive minha primeira introdução ao assunto em Linguagens de Programação: Aplicações e Interpretação
http://www.plai.org/
Tentarei resumir a ideia abstrata seguida de detalhes que não achei imediatamente óbvios. Em primeiro lugar, a inferência de tipo pode ser pensada para gerar e, em seguida, resolver restrições. Para gerar restrições, você percorre novamente a árvore de sintaxe e gera uma ou mais restrições em cada nó. Por exemplo, se o nó for um+ operador, os operandos e os resultados devem ser todos números. Um nó que aplica uma função tem o mesmo tipo que o resultado da função e assim por diante.
Para uma linguagem sem let, você pode resolver cegamente as restrições acima por substituição. Por exemplo:
(if (= 1 2)
1
2)
aqui, podemos dizer que a condição da instrução if deve ser booleana e que o tipo da instrução if é o mesmo que o tipo de suas cláusulas thene else. Visto que sabemos 1e 2somos números, por substituição, sabemos que a ifafirmação é um número.
Onde as coisas ficam feias, e o que eu não conseguia entender por um tempo, é lidar com isso:
(let ((id (lambda (x) x)))
(id id))
Aqui, associamos ida uma função que retorna tudo o que você passou, também conhecido como função de identidade. O problema é que o tipo de parâmetro da função xé diferente em cada uso de id. A segunda idé uma função do tipo a -> a, onde apode ser qualquer coisa. O primeiro é do tipo (a -> a) -> (a -> a). Isso é conhecido como polimorfismo let. A chave é resolver as restrições em uma ordem particular: primeiro resolva as restrições para a definição de id. Isso vai ser a -> a. Em seguida, cópias novas e separadas do tipo de idpodem ser substituídas nas restrições de cada local id, por exemplo a2 -> a2e a3 -> a3.
Isso não foi explicado prontamente nos recursos online. Eles mencionarão o algoritmo W ou M, mas não como eles funcionam em termos de resolução de restrições, ou por que ele não vomita no polimorfismo let: cada um desses algoritmos impõe uma ordem na resolução das restrições.
Achei este recurso extremamente útil para amarrar o Algoritmo W, M e o conceito geral de geração de restrição e resolução de todos juntos. É um pouco denso, mas melhor do que muitos:
http://www.cs.uu.nl/research/techreps/repo/CS-2002/2002-031.pdf
Muitos dos outros papéis também são bons:
http://people.cs.uu.nl/bastiaan/papers.html
Espero que ajude a esclarecer um mundo um tanto obscuro.