Think of the type of inference as solving a system of equations. Let me take a look at an example:
fx = (x,2)
How can we infer type f ? We see that this is a function:
f :: a -> b
In addition, the structure f shows that the following equations simulate:
b = (c,d) d = Int c = a
Solving this system of equations, we see that the type f is equal to a -> (a, Int) . Now consider the following (erroneous) function:
fx = x : x
Type (:) is equal to a -> [a] -> [a] , so this generates the following system of equations (simplified):
a = a a = [a]
So, we get the equation a = [a] , from which we can conclude that this system of equations has no solution, so the code is not well typed. If we did not reject the equation a = [a] , we would really go into an infinite loop, adding to our system the equations a = [a] , a = [[a]] , a = [[[a]]] and t .d. Etc. (Alternatively, as Daniel points out in his answer, we could allow infinite types in our type system, but that would make erroneous programs like fx = x : x for typecheck).
You can also check this in ghci:
> let fx = x : x <interactive>:2:15: Occurs check: cannot construct the infinite type: a0 = [a0] In the second argument of `(:)', namely `x' In the expression: x : x In an equation for `f': fx = x : x
As for your other questions: the GHC Haskell type system is not Turing-complete and the typechecker is guaranteed to stop - unless you turn on UndecidableInstances , in which case it could theoretically go in an infinite loop. However, the GHC provides termination using the recursion stack with a fixed depth, therefore it is impossible to create a program on which it never stops ( edit: according to the CAMcCann comment, this is possible in the end - there is an analog of tail recursion at the type level that allows you to loop without increasing stack depth).
Nevertheless, it is possible to compile arbitrarily for a long time, since the complexity of Hindley-Milner type inference is exponential in the worst (but not average!) Case:
dup x = (x,x) bad = dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup . dup
Safe Haskell does not protect you from this - see mueval if you want to allow potentially malicious users to compile Haskell programs on your system.