Arrays Haskell中的固定大小列表(即具有类似列表的API的数组)

Arrays Haskell中的固定大小列表(即具有类似列表的API的数组),arrays,list,haskell,Arrays,List,Haskell,Haskell中是否有高效的固定大小列表库?我认为,IArray接口有点复杂,因为人们只需要按自然数(包括零)索引的数组。我想写这样的代码 zeroToTwenty :: Int -> FixedList Int zeroToTwenty 0 = createFixedList 21 [] zeroToTwenty n = zeroToTwenty (n-1) `append` n 下面是我天真的解决方案 编辑:很抱歉没有上下文;我想要一个可以分配一次的数据结构,以避免过度的垃圾收集。这

Haskell中是否有高效的固定大小列表库?我认为,
IArray
接口有点复杂,因为人们只需要按自然数(包括零)索引的数组。我想写这样的代码

zeroToTwenty :: Int -> FixedList Int
zeroToTwenty 0 = createFixedList 21 []
zeroToTwenty n = zeroToTwenty (n-1) `append` n
下面是我天真的解决方案


编辑:很抱歉没有上下文;我想要一个可以分配一次的数据结构,以避免过度的垃圾收集。这是在用于合并排序的
merge
例程的上下文中进行的,该例程接受两个已排序的子列表并生成一个已排序的列表。

以下是我的简单解决方案

import Data.Array.Diff
newtype FixedList a = FixedList (Int, (DiffArray Int a))
createFixedList n init = FixedList (0, array (0, n - 1) init)
append (FixedList (curr, array)) v = FixedList (curr + 1, array // [(curr, v)])

instance Show a => Show (FixedList a) where
    show (FixedList (curr, arr)) = show $ take curr (elems arr)

使用这个软件包怎么样?它提供了一个非常有效的可增长向量,具有类似列表的接口,以及O(1)索引。

< P>我可能会使用Don Stewart建议的向量,但是您可以使用一个类似列表的接口,使用<代码> IArray <代码>。

< P>您可以考虑使用A。它提供摊销的O(1)cons、snoc、uncons和unsnoc,以及O(log n)split。

顺便说一句,diff数组已被弃用,它们的性能也相当差。@Don Stewart:谢谢!Vector是最好的替代品吗?对不起,太懒了;它在包页面上说
cons
是O(n)——这并不是我想要的(尽管我知道了之后肯定会使用vector)。事实上,cons是O(n)。但是,您可以通过
replicate
和其他组合器有效地创建固定大小的向量。请远离列表ish
cons
。好吧,我想要一个列表ish API:),也许我可以将它与下面的内容结合起来?@gatoatigrado,奇怪的是,当你专门寻找一个固定大小的列表库时,你会想要cons。@luqui问题是,如果你知道列表的最终大小,以前的代码可以毫不费力地重构。一般来说,人们可能希望采用2次方再分配方案。我希望询问者知道,通过
ListLike
包装数组不会神奇地提供O(1)时间限制。(参见提问者对唐·斯图尔特回答的评论。)@Tsuyoshi Ito:这是一个非常好的观点
ListLike
只是一个界面;实现的性能特征不会改变。如果
cons
和索引都很重要,我可能建议使用Data.Sequence。但要提出一个真正的建议,还需要更多的上下文。列表中没有给出的数据类型对您的期望是什么?是O(1)索引吗?为了得到O(1)索引,你愿意交换什么?我仍然不知道你期望什么样的操作。在Haskell中,一次性分配的内容也必须一次性填充。除非你想使用可变的数据结构。@augustss diffarray在内部使用monad(根据Wikipedia),所以元素替换是常数时间。当以持久方式使用差异数组时,其复杂性非常奇怪。