【发布时间】:2019-04-20 12:29:42
【问题描述】:
我目前正在学习 Haskell,并使用 List。
根据HaskellWiki,如果我想将两个列表合并在一起,我会写:
list1 ++ list2
但是,根据this 的回答,在大列表上使用 ++ 会效率低下。
通过研究,我遇到了this SO page,但这个问题需要对List 的输出有特定要求。
我尝试了什么:
假设如果我有两个数字列表(对于这个例子,假设两个列表都足够大,以至于使用++ 将是低效的,如 SO 答案中所述):
oldNumbers = [1,5,14,22,37]
newNumbers = [3,10,17,27,34,69]
allNumbers = oldNumbers:newNumbers
如您所见,我试图将oldNumbers 添加到newNumbers 的头部,以便之后将其反转(忽略allNumbers 现在是无序的,这是另一天的练习)。
正如你可能猜到的那样,它产生了一个错误
error:
* Non type-variable argument in the constraint: Num [a]
(Use FlexibleContexts to permit this)
* When checking the inferred type
allNumbers :: forall a. (Num a, Num [a]) => [[a]]
那么,如标题所述,如何有效地合并两个列表?
【问题讨论】:
-
(++)在线性时间工作的意义上并不是低效的。这个想法是(++)但是有时被“滥用”以将单个元素附加到列表中,从而将算法转换为 O(n^2) 而不是 O(n). -
正确性第一,效率第二。真的。 -- 那么你是在合并两个排序的列表,合并的列表也必须排序吗?如果没有,一次性
++绝对没有问题。你引用的答案谈到 repeated 附加 one-element 列表,++ [x]是“坏的”。 -
@WillNess - 合并后的列表不需要排序。我正在采取一些小步骤,所以现在的任务是合并这两个列表。当我更好地理解 Haskell 中的
List时,我会sort他们。 -
然后
++完成这项工作。你想重新实现它,作为一个练习吗?你的问题是关于那个,还是关于你得到的错误? -
嘿,这就是我的回答。我从未说过
++效率低下。
标签: list haskell merge compiler-errors