List 将元素添加到列表末尾的正确方法?
我在Haskell页面上读到关于在List 将元素添加到列表末尾的正确方法?,list,haskell,List,Haskell,我在Haskell页面上读到关于在列表的末尾添加元素的内容 用这个例子,我自己尝试了一下。考虑到下面的列表,我想在其末尾添加编号56 例如: let numbers = [4,8,15,16,23,42] numbers ++ [56] 我被下面的评论吓坏了: 将项目添加到列表的末尾是一个很好的练习,但通常 你不应该在真正的Haskell程序中这样做。它很贵,而且 表示您正在以错误的顺序生成列表。有 通常是更好的方法 ,我意识到我实际上在做的是创建一个列表,其中56是唯一的元素,我将它与数字
列表的末尾添加元素的内容
用这个例子,我自己尝试了一下。考虑到下面的列表
,我想在其末尾添加编号56
例如:
let numbers = [4,8,15,16,23,42]
numbers ++ [56]
我被下面的评论吓坏了:
将项目添加到列表的末尾是一个很好的练习,但通常
你不应该在真正的Haskell程序中这样做。它很贵,而且
表示您正在以错误的顺序生成列表。有
通常是更好的方法
,我意识到我实际上在做的是创建一个列表
,其中56
是唯一的元素,我将它与数字
列表
相结合。对吗
使用
++
是将元素添加到列表末尾的正确方法吗?这是正确的方法,因为所有这样做的方法都必须减少至少那么多的工作量。问题是根本不想在列表的末尾追加内容。对于不可变的链表来说,这不是一个有效的操作
更好的方法是找出如何在不这样做的情况下解决您的特定问题。有很多潜在的方法。选择正确的一个取决于你所做的细节。也许你可以正确地利用懒惰来逃避惩罚。也许你最好向后生成列表,然后在最后反转一次。也许您最好使用不同的数据结构。这完全取决于您的特定用例 ++[x]
是将元素添加到列表末尾的正确方法,但注释的意思是不应将元素添加到列表末尾
由于列表的定义方式,在末尾添加元素始终需要制作列表的副本。就是
xs ++ ys
需要复制所有的xs
,但可以重复使用ys
不变
如果xs
只是一个元素(即,我们将添加到列表的开头),那就没有问题:复制一个元素几乎不需要任何时间
但是如果xs
更长,我们需要在++
上花费更多的时间
如果我们重复这样做(即,我们通过不断在末尾添加元素来建立一个大列表),那么我们需要花费大量时间制作冗余副本。(以这种方式构建n元素列表是一个O(n2)操作。)
如果需要这样做,通常有更好的方法来构造算法。例如,您可以按相反的顺序构建列表(在开始时添加元素),并且只在末尾调用reverse
。您熟悉[a]
的定义吗?这是一个嵌套的结构,就像一个俄罗斯娃娃:列表的“结尾”最好被认为是中心。如果你想添加一个新的最小的玩偶,你需要打开每一层(O(n)操作)。试着为自己实现++
“这很昂贵,并且表明您正在以错误的顺序构建列表。通常有更好的方法”这一部分非常重要。也许你应该专注于如何以相反的顺序创建你的numbers
列表,然后像56:numbers
那样提高效率。