我是 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”?
感谢您的帮助,对不起,如果这是一个非常基本的问题。
答案 0 :(得分:12)
这个想法是功能性编程的核心:你(通常)不会在适当的位置修改数据。因此,您不要将项目添加到列表中:您创建新列表而不修改旧列表。
这允许许多好东西,例如共享,因为您永远不会更改旧数据,因此您可以继续引用它。但是如果你习惯于其他编程范例,它也会带来负担:你必须改变你的方法来处理事物(通常你必须改变你的数据结构/算法,因为他们依赖于数据结构的就地修改)
在您的示例中,只需为cons'ed列表指定一个新名称:
let a = [1, 2, 3]
let b = 5:a
答案 1 :(得分:7)
你的误解是根本的:利弊不会破坏性地修改任何东西。
5:a
(其中a = [1,2,3]
)评估为[5,1,2,3]
,这就是口译员向您展示的内容。
答案 2 :(得分: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]
使用'let'进行的绑定永远不会改变,但可以创建新的绑定。如果新绑定与旧绑定具有相同的名称,则旧绑定将被“遮蔽”而不会发生变异。
答案 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。