35

我经常听到有人声称 Haskell 没有变量。特别是,这个答案声称它没有,并且它至少被投票九次并被接受。

那么它是否有变量,为什么?

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

4

5 回答 5

57

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 有真正的变量。但它默认不使用可变变量。

于 2009-06-14T21:19:08.163 回答
10

简单的答案是:是的,Haskell 具有Haskell 报告第 3.2 节中定义的变量。变量可以出现在模式中,因此可以使用 、 和列表推导等结构绑定到一个letcase

您的问题中可能隐含的是,如果变量是不可变的,则该变量是否被正确称为变量。我认为其他答案充分涵盖了可变性。

于 2009-06-14T22:12:41.527 回答
9

是的,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)))
于 2009-06-14T16:16:17.827 回答
4

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

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

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

[数学变量] ( http://en.wikipedia.org/wiki/Variable_(mathematics))上的页面可以提供对此的进一步了解。

于 2009-06-15T01:05:47.523 回答
2

“我听说 Haskell 没有变量。这是真的吗?”

没有

“那么它有没有变量,为什么?”

是的。

编辑:我的回答会导致双重否定,这自然会令人困惑,因为标题问题是肯定的,而正文不是。:)

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

于 2009-06-14T16:16:28.263 回答