When evaluating a let-statement of the form let foo = bar in baz, foo is already bound to bar while evaluating bar - that is definitions are recursive and if there is an outer binding with the same name, it is simply ignored as it is no longer in scope.
In a comment you asked why you don't then get an error about the lookup of x failing. The reason for that is that the lookup of x does not fail. Haskell knows that x is equal to x * x, so that's what the lookup produces.
So when x is evaluated, it is replaced with its definition x * x. To evaluate that it then replaces the first of the xs with its definition, yielding x * x * x, then x * x * x * x and so on ad infinitum.
You might wonder why values are allowed to be recursive that way, so here's an example that is actually useful and does not just lead to an infinite loop: let xs = 42 : xs in take 2 xs produces the result [42, 42]. Here xs is expanded to 42 : xs and then 42 : 42 : xs and then it stops because take 2 only needs the first two elements, so that's where it stops.
And of course when the rhs is a function, it's immediately obvious that it's useful for the definition to be recursive: let fac = \n -> if n = 0 then 1 else n * fac (n-1) - here you obviously want fac to refer to itself and not some previous definition of fac.
let x = x * x, it's all the samex, not the one from the outer scope.xfails?map f [] = []; map f (x:xs) = f x : map f xs. We want the instance ofmapto the right of the=to be the same as themapon the left side of the=. There is even the functionfixwhich is defined asfix f = let x = f x in x, and it can actually produce valuable results, a trivial one beingfix (1:), which creates an infinite lazy list of1s that refers to the same1over and over again so it won't blow up in RAM.x = x * x? I think if you first evaluatexin the RHS ofx = x * xthen there would be no problem. However, if you first evaluatex = x * xwithout first evaluating thexin the RHS,xis bound tox * x, then evaluating thexinx * xwould lead to this non-termination, right?