Regarding finger trees, as seen in this paper and mentioned in this post by Eric Lippert.
I do not understand why an explicit tuple arrangement is used, as opposed to some sort of linked list structure for each finger. That is, why do we define One(x), Two(x, y), Three(x, y, z), Four(x, y, z, a) and not just have a less optimal deque object and do LessOptimalDeque.AddLeft(x)?
Is it somehow slower? I mean, even though you could use some data structure that re-uses the memory of some nodes/groups of nodes?
In the paper, it’s even mentioned:
Exercise 1. In the above presentation, we represented digits as lists for simplicity.
A more accurate and efficient implementation would use the type
data Digit a = One a
| Two a a
| Three a a a
| Four a a a a
Rework the above denitions to use this denition of Digit.
I don’t know why it’s more efficient though. Is it only something relevant to the functional language the author was using, and otherwise could also be done using the data structures I proposed above?
Edit
What about implementing the finger like this?
To see why this is more efficient in Haskell:
than this (the obvious encoding of a vector):
we can observe the heap structure necessary to allocate a
Digitvs aList.vs
In the former case, we save 3 constructors. In the latter we are forced to allocate additional heap objects for the (possibly infinite) tail of the structure. In general, the
Digitrepresentation will allocate O(n-1) fewer heap cells, as the size of the structure is encoded in the outermost constructor. We can also determine the size in O(1) as a result.