【发布时间】:2012-02-16 10:32:18
【问题描述】:
Recently 我被介绍给this OCaml code,在 Haskell 中可以写成:
data DL a = DL [a] a [a]
create [] = error "empty list"
create (x:xs) = DL [] x xs
next (DL pr x (h:tl)) = DL (x:pr) h tl
next _ = error "end of dlist"
prev (DL (p:pr) x tl) = DL pr p (x:tl)
prev _ = error "start of dlist"
我认为 不是 一个合适的双向链表实现,因为它在遍历时创建了新的存储。 OTOH 还有this Haskell code:
data DList a = Leaf | Node { prev::(DList a), elt::a, next::(DList a) }
create = go Leaf
where go _ [] = Leaf
go prev (x:xs) = current
where current = Node prev x next
next = go current xs
我们可以说只有这个代码是真正的 dl-list吗?
我们能否依靠这段代码引入真正的 dl-list 节点共享,从而在遍历时不会创建新的存储?
Haskell 中的同名变量是否总是指代相同的“事物”,还是可能单独出现的同名变量引用同一事物的不同副本? strong>(经过编辑以增加重点)。
【问题讨论】:
-
第一个实现是所谓的Zipper;可以说它可以用于单链表或双链表。但是,它本身并不是一个列表实现。
-
如果您仔细阅读 Haskell 报告,您将找不到任何关于如何表示数据的段落。请记住,所有类型的共享都依赖于实现,尽管实现某个功能的方式大多只有几种合理的方式。
-
感谢您提出这个问题!我对我的不满意,正在关注这个。
-
@WillNess GHC 非常注意不要重复计算。一旦一个表达式被计算为 WHNF,它就可以被复制而无需重复工作。
-
我不是 100% 确定 GHC 对空间安全,但在正常情况下它不会复制数据。
标签: haskell functional-programming linked-list