我经常听说Haskell没有变量的说法;特别是,this answer声称它没有,并且它至少被投票了九次并被接受。
它是否有变量,为什么?
这个问题似乎也适用于ML,F#,OCaml,Erlang,Oz,Lava和所有SSA中间语言。
答案 0 :(得分:51)
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
所以,是 Haskell有真正的变量。但默认情况下它不使用可变变量。
答案 1 :(得分:9)
简单的答案是:是的,Haskell具有Section 3.2 of the Haskell Report中定义的变量。变量可以出现在模式中,因此可以使用let
,case
和列表推导等结构绑定到值。
如果变量是不可变的,那么在你的问题中可能隐含的是变量是否被恰当地称为变量。我认为其他答案足以涵盖可变性。
答案 2 :(得分:5)
是的,Haskell有变量。考虑(基本上等效的)定义
inc n = n + 1
inc = \n -> n + 1
在这两种情况下,n
都是变量;它会在不同的时间呈现不同的价值观。 Haskell Report中的Section 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
之后,如果没有引入新的n
范围(这是一个不同的变量,影响另一个n
,则它不能是42 {}。 })绑定到另一个值。
在某些情况下,例如使用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)))
答案 3 :(得分:3)
“我听说Haskell没有变量。这是真的吗?”
“它是否有变量,为什么?”
编辑:我的回答导致双重否定,这自然令人困惑,因为标题问题是积极的,而身体则不是。 :)EDIT2:再次编辑,因为OP改变了问题。
答案 4 :(得分:3)
根据[维基百科](http://en.wikipedia.org/wiki/Variable_(programming)),是的,Haskell有变量:
在计算机编程中,变量是一个标识符(通常是字母或单词),它链接到存储在系统内存中的值或可以计算的表达式。例如,变量可能被称为“total_count”并包含一个数字。
在命令式编程语言中,通常可以随时访问或更改值。但是,在纯函数和逻辑语言中,由于引用透明性的要求,变量绑定到表达式并在其整个生命周期中保持单个值。在命令式语言中,常量表现出相同的行为,这通常与正常变量形成对比。
当然,并非所有维基百科的定义都是完全值得信赖的。
[数学变量]页面(http://en.wikipedia.org/wiki/Variable_(mathematics)))可以进一步了解这一点。