【问题标题】:Does Haskell have variables?Haskell 有变量吗?
【发布时间】:2010-11-02 20:22:20
【问题描述】:

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

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

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

【问题讨论】:

  • 这个问题并不真正适用于 SSA。 SSA 没有可变变量的原因与 Haskell 不同。 Haskell 没有可变变量来尊重引用透明性。 SSA 没有可变变量来帮助分析。
  • @xilpex 您的评论 begs the question 假设 SSA 和 Haskell 都有“变量”。请注意,我的问题不是关于为什么语言具有不可变变量_,而是关于这些是否可以被视为变量。

标签: variables haskell immutability monads referential-transparency


【解决方案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

所以,是的 Haskell 有真正的变量。但它默认不使用可变变量。

【讨论】:

    【解决方案2】:

    是的,Haskell 有变量。考虑(本质上等价的)定义

    inc n = n + 1
    inc = \n -> n + 1
    

    在这两种情况下,n 都是一个变量;它将在不同的时间采用不同的值。 Section 3 中的 Haskell Report 将这些明确地称为变量。

    这里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
    

    但是如果您删除语法糖,将其翻译成没有 do 的 Haskell,很明显创建了一个新的嵌套范围,其中该内部范围中的 n 是一个不同的变量,它隐藏了n 在外部范围内:

    (let n = 1 
      in (print n >> (let n = 2
                       in print n)))
    

    【讨论】:

    • Haskell 中没有变量!可以重新分配变量。您在函数或 let-bindings 中拥有的只是一个不可变的函数参数,一个绑定到名称的值!
    • 达里奥,维基百科不同意,列出了所有变量都是单赋值的九种语言和另外五种可以选择单赋值的语言:en.wikipedia.org/wiki/Single_assignment。此外,提出该术语的数学家也使用单赋值意义上的变量。如果您要对此提出异议,请发布详细的答案,说明为什么这是错误的观点?
    【解决方案3】:

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

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

    当然,并非所有 Wikipedia 定义都完全值得信赖。

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

    【讨论】:

      【解决方案4】:

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

      No.

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

      Yes.

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

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

      【讨论】:

      • 您能引用您回答的问题吗?现在,当我打开这个题为“Haskell 有变量吗?”的问题时。我看到的第一个答案是“不”。 (显然,我实际上并没有阅读完整的问题,只是标题。)
      【解决方案5】:

      简单的答案是:是的,Haskell 有在Section 3.2 of the Haskell Report 中定义的变量。变量可以出现在模式中,因此可以使用 letcase 和列表推导等结构绑定到一个值。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多