It is valid because it defines + instead.
main = print (3 + 4)
where -- silly redefinition of `+` follows
0 + y = y
x + y = x * ((x-1) + y)
Above, the Prelude (+) function is shadowed by a local binding. The result will be 24, not 7, consequently.
Turning on warnings should point out the dangerous shadowing.
<interactive>:11:6: warning: [-Wname-shadowing]
This binding for ‘+’ shadows the existing binding