Cons的优点是什么?

时间:2013-04-24 01:37:52

标签: data-structures functional-programming

许多功能性编程语言支持并推荐数据构造函数Cons(适用于(1, (2, (3)))之类的列表,例如HaskellScala。< / p>

但它有什么优势?此类列表既不能随机访问,也不能附加到O(1)

2 个答案:

答案 0 :(得分:6)

Cons(“构造”的简写)不是数据结构,它是用于创建 cons-cell 操作的名称。并且通过将几个单元链接在一起,可以构建数据结构,尤其是链接列表。讨论的其余部分假定使用cons操作创建链接列表。

虽然可以在头部附加O(1),但是通过索引随机访问元素是一项代价高昂的操作,需要遍历所有元素,然后才能访问所有元素。

链表的优势?它是一个功能数据结构,在修改时创建或重新创建便宜;它允许在几个列表之间共享节点,并允许轻松垃圾收集。它非常灵活,通过正确的抽象,可以表示其他更复杂的数据结构,如堆栈,队列,树,图。并且有许多专门用于操作列表的程序 - 例如mapfilterfold等,这使得使用列表成为一种乐趣。最后,列表是递归数据结构,递归(特别是尾递归)是解决函数式编程语言中问题的首选方法;所以在这些语言中,将递归数据结构作为主要数据结构是很自然的。

答案 1 :(得分:2)

首先,让我们将“cons”区分为通常称为::的ML样式列表数据构造函数的昵称,以及昵称来自的原始Lisp样式cons函数。

在Lisps中,cons单元是一种通用数据结构,不限于同类元素类型列表。 ML风格语言中的等价物将是嵌套对或2元组,由“单元”类型表示的空列表通常写为()。 ÓscarLópez对Lisp cons的效用给出了很好的概述,所以我将其留在那里。

在大多数ML风格的语言中,不可变缺点列表的优点与它们在Lisps中的列表的使用没有太大区别,为了保证静态类型和ML样式模式匹配的语法而牺牲了动态类型的灵活性。

然而,在Haskell中,由于懒惰的评估,情况相当不同。构造函数是惰性的,它们之间的模式匹配是强制评估的几种方法之一,因此与严格评估的语言相比,通常情况下你应该避免尾递归。相反,通过将递归调用放在列表的尾部,可以仅在需要时计算每个递归调用。如果使用适当的惰性函数(如mapfoldr)处理延迟生成的列表,则可以在常量内存中构造和使用大型列表,尾部强制以相同的速率处理头部放弃让GC清理。

Haskell的一个共同观点是,懒惰的缺点列表不是一个数据结构,而是一个控制结构 - 一个与其他这样的循环有效组合的具体循环。

也就是说,在很多情况下,缺点列表是合适的 - 例如当需要重复随机访问时 - 并且在那些使用列表的情况下肯定不推荐。