Имеет ли 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)) может дать дальнейшее понимание этого.