List Data.map中haskell中列表的复杂性

List Data.map中haskell中列表的复杂性,list,haskell,map,time-complexity,List,Haskell,Map,Time Complexity,如果这似乎是一个显而易见的问题,那么很抱歉 我正在创建一个列表的Data.map{实际上是一个整数和一个列表(integer,[(integer,integer)])的元组,用于实现一些图形算法(如Dijkstras和Prims)的优先级队列+邻接列表 Data.map是使用二叉树实现的(我读到了),所以我只想确认,当执行映射操作时(我相信它们将是旋转),解释器不会执行列表的深度拷贝,而只是列表引用的浅拷贝,对吗 我这样做是为了在haskell中实现prims算法,该算法将在O(nlogn+ml

如果这似乎是一个显而易见的问题,那么很抱歉

我正在创建一个列表的Data.map{实际上是一个整数和一个列表(integer,[(integer,integer)])的元组,用于实现一些图形算法(如Dijkstras和Prims)的优先级队列+邻接列表

Data.map是使用二叉树实现的(我读到了),所以我只想确认,当执行映射操作时(我相信它们将是旋转),解释器不会执行列表的深度拷贝,而只是列表引用的浅拷贝,对吗

我这样做是为了在haskell中实现prims算法,该算法将在O(nlogn+mlogn)时间内运行,其中n=顶点数,m=边数,以纯函数方式, 如果列表存储在优先级队列中,算法将在该时间内工作。我在网上找到的大多数haskell实现都没有达到这种复杂性


提前感谢。

您是正确的,至少在您使用GHC的情况下,不会在每次创建新的
地图时复制列表(其他实现可能也会正确执行此操作)。这是纯函数式语言的优点之一:因为数据不能重写,所以不需要复制数据结构来避免在命令式语言中可能出现的问题。考虑Lisp的这个片段:

(setf a (list 1 2 3 4 5))
(setf b a)
; a and b are now both '(1 2 3 4 5).
(setf (cadr a) 0)
; a is now '(1 0 3 4 5).
; Careful though! a and b point to the same piece of memory,
; so b is now also '(1 0 3 4 5). This may or may not be what you expected.
在Haskell中,拥有这种可变状态的唯一方法是使用显式可变的数据结构,例如
状态
monad中的某些内容(甚至这也是一种伪装(这是一件好事))。这种潜在的意外内存复制问题在Haskell中是不可想象的,因为一旦您声明
a
是一个特定的列表,它现在和永远都是该列表。因为它保证永远不会改变,所以将内存重新用于应该相等的事情是没有危险的,事实上,GHC会做到这一点。因此,当您使用相同的值创建新的
映射时,将只复制指向值的指针,而不会复制值本身

有关详细信息,请阅读。

1)
Integer
Int

2) 如果您有
[(整数,[(整数,整数)]]

您可以使用
Data.Map
创建,不仅
Map Integer[(Integer,Integer)]
,而且
Map Integer(Map Integer Integer)

3) 如果使用
Int
而不是
Integer
,则可以使用
data.IntMap
中更快的数据-
IntMap
IntMap(IntMap Int)

4) 每种方法的复杂性都写在描述中: 在这里:


Haskell本身并没有对此做出任何承诺,但据我所知,没有一个实现能够实现深度复制。
map :: (a -> b) -> IntMap a -> IntMap b
O(n). Map a function over all values in the map.