我经常听到有人声称 Haskell 没有变量。特别是,这个答案声称它没有,并且它至少被投票九次并被接受。
那么它是否有变量,为什么?
这个问题似乎也适用于 ML、F#、OCaml、Erlang、Oz、Lava 和所有SSA中间语言。
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 有真正的变量。但它默认不使用可变变量。
简单的答案是:是的,Haskell 具有Haskell 报告第 3.2 节中定义的变量。变量可以出现在模式中,因此可以使用 、 和列表推导等结构绑定到一个let
值case
。
您的问题中可能隐含的是,如果变量是不可变的,则该变量是否被正确称为变量。我认为其他答案充分涵盖了可变性。
是的,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
, as we expandinc
x
将采用 value 0
,当稍后(或更早!)评估g
时, as we expandinc
x
将采用 value 1
。
可能会出现一些混淆,因为 Haskell 与问题中列出的其他语言一样,是一种单赋值语言:它不允许在范围内重新分配变量。一旦n
被分配了 value 42
,它只能是 42 而不引入一个新的范围,新的n
(这是一个不同的变量,遮蔽了 other 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)))
根据 [Wikipedia]( http://en.wikipedia.org/wiki/Variable_(programming)),是的,Haskell 有变量:
在计算机编程中,变量是一个标识符(通常是一个字母或单词),它与存储在系统内存中的值或可以计算的表达式相关联。例如,一个变量可能被称为“total_count”并包含一个数字。
在命令式编程语言中,通常可以随时访问或更改值。但是,在纯函数和逻辑语言中,由于引用透明性的要求,变量绑定到表达式并在其整个生命周期内保持一个值。在命令式语言中,常量表现出相同的行为,通常与普通变量形成对比。
当然,并不是所有维基百科的定义都完全值得信赖。
[数学变量] ( http://en.wikipedia.org/wiki/Variable_(mathematics))上的页面可以提供对此的进一步了解。