Да, в Haskell есть переменные. Рассмотрим (по существу эквивалентные) определения
inc n = n + 1
inc = \n -> n + 1
В обоих этих случаях n
является переменной; он будет принимать разные значения в разное время. Отчет по Haskell в Раздел 3 явно указывает на них как на переменные.
То, что n
здесь - переменная, может быть легче увидеть, если мы рассмотрим следующую завершенную программу:
inc n = n + 1
f = inc 0
g = inc 1
main = print (f+g)
Ответом будет «3», конечно. При оценке f
при расширении inc
x
примет значение 0
, а когда позже (или раньше!) При оценке g
при расширении inc
x
примет значение 1
.
Некоторая путаница могла возникнуть из-за того, что Haskell, как и другие языки, перечисленные в вопросе, является языком с одним назначением: он не позволяет переназначать переменные в области видимости. Как только n
было присвоено значение 42
, оно не может быть ничем иным, как 42, без введения новой области видимости с новой n
(которая является другой переменной, затеняя другую n
), связанной с другим значением.
Это может быть не совсем очевидно в некоторых контекстах, таких как выражения, использующие do
:
do let n = 1
print n
let n = 2
print n
но если вы удалите синтаксический сахар, переведя его на Haskell без do
, станет ясно, что была создана новая вложенная область действия, где n
во внутренней области является другой переменной, которая затеняет n
во внешнем объеме:
(let n = 1
in (print n >> (let n = 2
in print n)))