7

我是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”?

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

4

4 回答 4

12

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

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

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

let a = [1, 2, 3]
let b = 5:a
于 2012-02-28T17:41:04.783 回答
7

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

5:a(其中a = [1,2,3]) 的计算结果为[5,1,2,3],这就是口译员向您展示的内容。

于 2012-02-28T17:37:30.937 回答
6

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

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]

用“让”制作的绑定永远不会改变,但可以制作新的。如果新绑定与旧绑定同名,则旧绑定将被“隐藏”而不是突变。

于 2012-02-28T17:56:28.653 回答
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

于 2012-02-28T17:38:56.353 回答