【问题标题】:How do I access a list element I've added with the cons (:) operator?如何访问使用 cons (:) 运算符添加的列表元素?
【发布时间】:2012-03-18 05:11:05
【问题描述】:

我是 Haskell(以及一般的函数式编程)的新手,想知道如何访问我使用 cons添加到列表中的新元素> (:) 运算符?

例如,使用 WinGHCi 创建一个新列表并访问第一个元素:

ghci> let a = [1,2,3]
ghci> a!!0
1

提示返回1,第一个元素的值,cool。现在我将一个新值附加到列表的前面并尝试访问它:

ghci> 5:a
[5,1,2,3]
ghci> a!!0
1

看起来列表项没有被重新索引。我试图让一个负索引工作和其他类似的事情,但编译器似乎没有批准。我正在阅读的教程只是跳过它,我在网上找不到任何有用的东西。如何从列表中获取值“5”?

感谢您的帮助,如果这是一个非常基本的问题,我们深表歉意。

【问题讨论】:

  • 为了说明 Marcin 的观点,在 GHCI 中输入“a”,您将看到 [1,2,3],因为您无法在 Haskell 中修改变量。为了澄清事情,请考虑these definitions of variable and assignable:Haskell 在数学意义上具有“变量”,但没有命令式语言中的“可赋值”。
  • a 在 5:a 之后仍然是 [1,2,3]。Thera 没有像函数式编程中的突变这样的副作用
  • 是的,我现在明白了,这完全是另一种想法……哈哈。谢谢大家!
  • Haskell 有不可变的数据。变量不存在 - 只有名称为变量的静态值存在。这确实是一个关于 Haskell 中基本概念的非常基本的问题。

标签: list haskell functional-programming winghci


【解决方案1】:

您的误解是根本性的:cons 不会破坏性地修改任何内容。

5:a(其中a = [1,2,3])的计算结果为[5,1,2,3],这就是解释器向您显示的内容。

【讨论】:

    【解决方案2】:

    列表是不可变的:

    Prelude> let xs = [1,2,3]
    Prelude> 4:xs
    [4,1,2,3]
    Prelude> xs
    [1,2,3]
    Prelude> let ys = 4:xs
    Prelude> ys
    [4,1,2,3]
    

    如果您想更改数据结构的元素,请使用Arrays

    【讨论】:

      【解决方案3】:

      这个想法是函数式编程的核心:你(通常)不会修改数据。因此,您无需将项目添加到列表中:您无需修改​​旧列表即可创建新列表。

      这允许许多美好的事情,例如共享,因为您永远不会更改旧数据,因此您可以继续引用它。但是,如果您习惯于其他编程范式,它也会带来负担:您必须改变处理事物的方式(并且通常您必须更改数据结构/算法,因为它们依赖于数据结构的就地修改) .

      在您的示例中,只需为 cons'ed 列表起一个新名称:

      let a = [1, 2, 3]
      let b = 5:a
      

      【讨论】:

        【解决方案4】:

        让我用 (+) 和 (:) 来说明

        Prelude> 4+5
        9
        Prelude> let z = 5
        Prelude> z
        5
        Prelude> 4+z
        9
        Prelude> z
        5
        Prelude> let y = 4+z
        Prelude> y
        9
        Prelude> z
        5
        

        Prelude> let a = [1,2,3]
        Prelude> a
        [1,2,3]
        Prelude> 5:a
        [5,1,2,3]
        Prelude> a
        [1,2,3]
        Prelude> let b = 5:a
        Prelude> b
        [5,1,2,3]
        Prelude> a
        [1,2,3]
        

        用“let”创建的绑定永远不会改变,但可以创建新的绑定。如果新绑定与旧绑定同名,则旧绑定被“隐藏”而不是变异。

        【讨论】:

          猜你喜欢
          • 2021-03-30
          • 1970-01-01
          • 2018-12-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-18
          • 2012-05-23
          • 1970-01-01
          相关资源
          最近更新 更多