Haskell有变量吗?

时间:2009-06-14 16:15:31

标签: variables haskell immutability monads referential-transparency

我经常听说Haskell没有变量的说法;特别是,this answer声称它没有,并且它至少被投票了九次并被接受。

它是否有变量,为什么?

这个问题似乎也适用于ML,F#,OCaml,Erlang,Oz,Lava和所有SSA中间语言。

5 个答案:

答案 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中定义的变量。变量可以出现在模式中,因此可以使用letcase和列表推导等结构绑定到值。

如果变量是不可变的,那么在你的问题中可能隐含的是变量是否被恰当地称为变量。我认为其他答案足以涵盖可变性。

答案 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没有变量。这是真的吗?”

No

“它是否有变量,为什么?”

Yes.

编辑:我的回答导致双重否定,这自然令人困惑,因为标题问题是积极的,而身体则不是。 :)

EDIT2:再次编辑,因为OP改变了问题。

答案 4 :(得分:3)

根据[维基百科](http://en.wikipedia.org/wiki/Variable_(programming)),是的,Haskell有变量:

在计算机编程中,变量是一个标识符(通常是字母或单词),它链接到存储在系统内存中的值或可以计算的表达式。例如,变量可能被称为“total_count”并包含一个数字。
在命令式编程语言中,通常可以随时访问或更改值。但是,在纯函数和逻辑语言中,由于引用透明性的要求,变量绑定到表达式并在其整个生命周期中保持单个值。在命令式语言中,常量表现出相同的行为,这通常与正常变量形成对比。

当然,并非所有维基百科的定义都是完全值得信赖的。

[数学变量]页面(http://en.wikipedia.org/wiki/Variable_(mathematics)))可以进一步了解这一点。