[英]Haskell: What's the underlying data structure for list?
If it's linked list, why doesn't it support push_back? 如果是链表,为什么它不支持push_back?
If it's simply array, why does it need linear time when accessed by subscript? 如果只是数组,为什么下标访问时需要线性时间?
Appreciated for your help. 感谢您的帮助。
Edit: We can append element in front of a list like this 1:[2,3]
, that's push_front; 编辑:我们可以将元素添加到像这样的列表的前面
1:[2,3]
,即push_front;。 but we can't do it this way: [2,3]:4
, that's push_back. 但是我们不能这样做:
[2,3]:4
,就是push_back。
ps. ps。 actually I borrow push_front/back from C++'s STL
实际上我是从C ++的STL借来的push_front / back
Haskell list are singly linked list. Haskell列表是单链接列表。 It supports appending to the end of the list, but it has to traverse the entire list for this operation.:
它支持追加到列表的末尾,但是必须遍历整个列表才能执行此操作:
λ> let x = [1,2,3]
λ> x ++ [4]
[1,2,3,4]
If by push_back
you mean adding an element to the end, of course it "supports" it. 如果通过
push_back
表示在末尾添加一个元素,那么它当然“支持”它。 To add an element x
to a list list
(and get a new list so constructed), use the expression list ++ [x]
. 要将元素
x
添加到列表list
(并获取如此构造的新列表),请使用表达式list ++ [x]
。
Beware though, that this is an O(n) operation, n being the length of list
. 但是请注意,这是一个O(n)操作,n是
list
的长度。
That's because it is a singly linked list. 那是因为它是一个单链表。 It also answers your other question about subscript.
它还回答您有关下标的其他问题。
Since the question asks about the "underlying implementation": 由于该问题询问“基础实施”:
The list type is (conceptually) defined like this: 列表类型(在概念上)定义如下:
data [a] = [] | a:[a]
You can't actually write this declaration, because lists have funky syntax. 您实际上不能编写此声明,因为列表具有时髦的语法。 But you can make exactly the same kind of thing yourself
但是你自己可以做同样的事情
data List a = Nil | a :* List a
infixr 5 :*
When you write something like [1,2,3]
, that's just special syntax for 1:2:3:[]
. 当您编写类似
[1,2,3]
,这只是1:2:3:[]
特殊语法。 Since :
associates to the right, this really means 1:(2:(3:[]))
. 由于
:
关联到右边,因此实际上意味着1:(2:(3:[]))
。 The functions on lists are all, fundamentally, based on pattern matching, which deals with just one constructor at a time. 从根本上说,列表上的函数全部基于模式匹配,而模式匹配一次只处理一个构造函数。 You may have to open up a lot of
:
constructors to get to the end of a list, and then build a bunch of :
constructors to put together a new version with an extra element at the end. 您可能必须打开很多
:
构造函数才能到达列表的末尾,然后构建一堆:
构造函数以将新版本放在一起并在末尾添加一个额外的元素。 Any functions (like ++
) that you may use will end up going through this sort of process internally. 您可能使用的任何函数(例如
++
)最终都会在内部经历这种过程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.