【发布时间】:2016-02-25 09:28:25
【问题描述】:
List 是 Haskell 的默认数据类型,为什么我们还需要 Data.Sequence? Data.Seq 是否意味着可以随机访问的 C 样式数组?
如果是,我想这意味着 Data.Sequence 存储在固定的内存缓冲区中,因此是急切的评估类型。只是一个猜测,你会帮助纠正吗?谢谢。
【问题讨论】:
标签: list haskell sequence evaluation eager
List 是 Haskell 的默认数据类型,为什么我们还需要 Data.Sequence? Data.Seq 是否意味着可以随机访问的 C 样式数组?
如果是,我想这意味着 Data.Sequence 存储在固定的内存缓冲区中,因此是急切的评估类型。只是一个猜测,你会帮助纠正吗?谢谢。
【问题讨论】:
标签: list haskell sequence evaluation eager
列表类型是单链表。因此,prepend、head 和 tail 都是 O(1)。但是,++ 在左侧列表的大小上是 O(n)。
相比之下,Data.Sequence 是一棵平衡树,所以对它的大多数操作都是 O(log n)。这不如 O(1) 快,但它可能快得多 O(n)。换句话说,您可以比列表更快地加入序列,但前置稍慢。
除此之外,这两种数据结构具有非常相似的属性;他们都很懒惰,他们都是参照透明的。 (序列必须是有限的。)
另见the documentation for Data.Sequence的开场白:
通用有限序列。除了有限且具有严格的操作之外,序列在有效支持更广泛的操作方面也不同于列表。
底层算法显然是described here。 (特别是,包括一个漂亮的图表。)
如果您想要数组,您需要查看Data.Array 和/或Data.Vector。
【讨论】:
cons、snoc、head 和 last 对应对象都为Data.Sequence 摊销O(1)。
Data.Sequence.Seq 不是手指树吗?
Seq 在元素上很懒惰但在脊椎上很严格,对吧?
Seq 将当前元素的数量保存在 Int 中。我猜很多Seq 函数使用Int 来自动平衡树。无限的Seq 会导致有趣的行为。