Haskell列表的内部表示?

时间:2013-02-25 08:47:09

标签: list haskell data-structures

Haskell支持一些用于递归列表的基本操作,例如headtailinitlast。我在内部想知道Haskell如何表示其列表数据?如果它是单链接列表,则随着列表的增长,initlast操作可能会变得昂贵。如果它是一个双向链表,那么所有四个操作都可以非常容易地进行 O(1) ,尽管会牺牲一些内存。无论哪种方式,对我来说都很重要,所以我可以编写适当的代码。 (尽管,函数式编程的精神似乎是“问它是做什么,而不是它是如何做的”)。

2 个答案:

答案 0 :(得分:28)

列表表示为......单链表。定义如下:

data [] a = [] | a : [a]

你可以写成:

data List a = Empty | Cons a (List a)

内存布局完全由此定义。

  • 构造函数是堆分配的
  • 内部多态字段是指向其他已分配节点的指针
  • 脊椎是懒惰的

所以你最终得到这样的东西:

enter image description here

因此head在此结构上 O(1),而last(++) O(n) < / p>

Haskell中的数据结构没有神奇之处 - 它们的直接定义完全清楚了复杂性(模数懒惰)。如果您需要不同的复杂性,请使用不同的结构(例如IntMap,Sequence,HashMap,Vector等)......

答案 1 :(得分:14)

Haskell列表是单链接的,因此consheadtail为O(1),而initlast为O( ñ)。

如果您需要更好的性能,请考虑使用Data.Sequence中的Seq类型,该类型提供对列表两端的O(1)访问。在内部,它使用2-3 finger trees