Yes, Haskell has variables. Consider the (essentially equivalent) definitions
inc n = n + 1
inc = \n -> n + 1
In both these cases, n
is a variable; it will take on different values at different times. The Haskell Report, in Section 3 refers to these explicitly as variables.
That n
here is a variable may be easier to see if we consider the following complete program:
inc n = n + 1
f = inc 0
g = inc 1
main = print (f+g)
The answer printed will be "3", of course. When evaluating f
, as we expand inc
x
will take on the value 0
, and when later (or earlier!) evaluating g
, as we expand inc
x
will take on the value 1
.
Some confusion may have arisen because Haskell, as with the other languages listed in the question, is a single-assignment language: it does not allow the reassignment of variables within a scope. Once n
has been assigned the value 42
, it cannot be anything but 42 without introducing a new scope with a new n
(which is a different variable, shadowing the other n
) bound to another value.
This may not be entirely obvious in some contexts, such as expressions using do
:
do let n = 1
print n
let n = 2
print n
but if you remove the syntactic sugar, translating it into Haskell without the do
, it becomes clear that there was a new, nested scope created where the n
in that inner scope is a different variable that is shadowing the n
in the outer scope:
(let n = 1
in (print n >> (let n = 2
in print n)))