Имеет ли Haskell переменные?

Я часто слышал утверждения о том, что у Haskell нет переменных; в частности, этот ответ утверждает, что это не так, и оно было поддержано по меньшей мере девять раз и принято.

У него есть переменные или нет, и почему?

Этот вопрос также кажется применимым для промежуточных языков ML, F #, OCaml, Erlang, Oz, Lava и всех SSA.

Ответ 1

Haskell имеет неизменяемые переменные (переменные в математическом смысле) по умолчанию:

 foo x y = x + y * 2

По умолчанию переменные не являются изменяемыми ячейками.

У Haskell также есть изменяемые ячейки, но вы включаете их явно:

 > import Data.IORef (newIORef, readIORef, writeIORef)
 > v <- newIORef 0
 > readIORef v
 0

 > writeIORef v 7
 > readIORef v
 7

Итак, YES Haskell имеет истинные переменные. Но он не использует изменяемые переменные по умолчанию.

Ответ 2

Простой ответ: да, Haskell имеет переменные, как определено в в разделе 3.2 отчета Haskell. Переменные могут отображаться в шаблонах и поэтому могут быть привязаны к значению с использованием конструкций типа let, case и списков.

Возможно, в ваших вопросах подразумевается, правильно ли называется переменная переменной, если она является неизменной. Я думаю, что другие ответы охватывают изменчивость в достаточной степени.

Ответ 3

Да, у Haskell есть переменные. Рассмотрим (по существу эквивалентные) определения

inc n = n + 1
inc = \n -> n + 1

В обоих случаях n является переменной; он будет принимать разные значения в разное время. Haskell Report, в Раздел 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)))

Ответ 4

"Я слышал, что у Haskell нет переменных. Это правда?"

Нет.

"Значит, у него есть переменные или нет, и почему?"

Да.

EDIT: Мой ответ вызывает двойное отрицание, что естественно сбивает с толку, потому что заголовок вопроса является положительным, а тело - нет.:)

EDIT2: снова отредактирован, так как OP изменил вопрос.

Ответ 5

Согласно [Википедии] (http://en.wikipedia.org/wiki/Variable_(programming)), да, у Haskell есть переменные:

В компьютерном программировании переменная является идентификатором (обычно буквой или словом), который связан со значением, хранящимся в системной памяти, или выражением, которое может быть оценено. Например, переменную можно назвать "total_count" и содержать число.
В императивных языках программирования в любой момент можно в любой момент получить или изменить значения. Однако в чистых функциональных и логических языках переменные привязаны к выражениям и сохраняют одно значение на протяжении всего их жизненного цикла из-за требований ссылочной прозрачности. В императивных языках одно и то же поведение проявляется константами, которые обычно контрастируют с нормальными переменными.

Не то, чтобы все определения Википедии были, безусловно, заслуживающими доверия.

Страница в [математические переменные] (http://en.wikipedia.org/wiki/Variable_(mathematics)) может дать дальнейшее понимание этого.