简体   繁体   English

Haskell:列表的基本数据结构是什么?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM