Почему "2 + x = 7" действителен Haskell?

Когда я пытаюсь скомпилировать

main = putStrLn $ show x where
    2 + x = 7

GHC жалуется

error: Variable not in scope: x
  |
1 | main = putStrLn $ show x
  |                        ^

Таким образом, кажется, что 2 + x = 7 сам по себе является синтаксически действительным, хотя на самом деле он не определяет x. Но почему это так?

Ответ 1

Он действителен, потому что он определяет + вместо этого.

main = print (3 + 4)
   where -- silly redefinition of '+' follows
   0 + y = y
   x + y = x * ((x-1) + y)

Выше, функция Prelude (+) затеняется локальной привязкой. Результат будет 24, а не 7, следовательно.

Включение предупреждений должно указывать на опасное затенение.

<interactive>:11:6: warning: [-Wname-shadowing]
    This binding for ‘+ shadows the existing binding

Ответ 2

Вы определяете локальную функцию, называемую +.

2 + x = 7 эквивалентно (+) 2 x = 7, что эквивалентно

(+) y x | y == 2 = 7

x является (неиспользуемым) параметром, и функция определяется только в том случае, если первый аргумент равен 2. Это не очень полезно, но это объясняет, почему x не видно снаружи.