I am looking for a Haskell data structure that stores an ordered list of elements and that is time-efficient at swapping pairs of elements at arbitrary locations within the list. It's not [a]
, obviously. It's not Vector
because swapping creates new vectors. Which data structure is efficient at this?
-
[a] is a linked list which is quite efficient at element manipulation. If your problem is efficient indexing then the solution will depend on the actual use case. Perhaps [zippers](https://wiki.haskell.org/Zipper) will help? – Anupam Jain Oct 04 '15 at 06:03
-
1Are you asking about [`Data.Vector.Mutable`](https://hackage.haskell.org/package/vector-0.11.0.0/docs/Data-Vector-Mutable.html)? – Bakuriu Oct 04 '15 at 06:08
-
Also look at [Ropes](https://en.wikipedia.org/wiki/Rope_%28data_structure%29) – Anupam Jain Oct 04 '15 at 06:08
-
This could definitely be a job for a mutable array, which will do this in constant time and space. But using a mutable data structure may not fit your use case - what exactly are you trying to do? – user2407038 Oct 04 '15 at 07:32
-
1It sounds like an `STArray` is what you are looking for. – jberryman Oct 04 '15 at 14:38
3 Answers
The most efficient implementations of persistent data structures, which exhibit O(1) updates (as well as appending, prepending, counting and slicing), are based on the Array Mapped Trie algorithm. The Vector data-structures of Clojure and Scala are based on it, for instance. The only Haskell implementation of that data-structure that I know of is presented by the "persistent-vector" package.
This algorithm is very young, it was only first presented in the year 2000, which might be the reason why not so many people have ever heard about it. But the thing turned out to be such a universal solution that it got adapted for Hash-tables soon after. The adapted version of this algorithm is called Hash Array Mapped Trie. It is as well used in Clojure and Scala to implement the Set and Map data-structures. It is also more ubiquitous in Haskell with packages like "unordered-containers" and "stm-containers" revolving around it.
To learn more about the algorithm I recommend the following links:

- 42,792
- 11
- 94
- 169
-
I was surprised to read that updates cost only O(1), even with the proviso on the tree height. That's pretty good. You may wish to mention some complexity bounds in your answer. – chi Oct 04 '15 at 08:05
-
Edward Kmett's been working on some similar structures. I'm not sure how close he is to a release. – dfeuer Oct 04 '15 at 16:27
Data.Sequence
from the containers
package would likely be a not-terrible data structure to start with for this use case.

- 707
- 3
- 8
Haskell is a (nearly) pure functional language, so any data structure you update will need to make a new copy of the structure, and re-using the data elements is close to the best you can do. Also, the new list would be lazily evaluated and typically only the spine would need to be created until you need the data. If the number of updates is small compared to the number of elements, you could make a difference list that checks a sparse set of updates first, and only then looks in the original vector.

- 14,674
- 2
- 34
- 49