Ralf Hinze and
Ross Paterson,
*Journal of Functional Programming* 16(2):197–217, 2006.
doi:10.1017/S0956796805005769

We present 2-3 finger trees, a functional representation of persistent sequences supporting access to the ends in amortized constant time, and concatenation and splitting in time logarithmic in the size of the smaller piece. Representations achieving these bounds have appeared previously, but 2-3 finger trees are much simpler, as are the operations on them. Further, by defining the split operation in a general form, we obtain a general purpose data structure that can serve as a sequence, priority queue, search tree, priority search queue and more.

The basic structure is expressed as a non-regular (or nested) type:

This produces trees of 2-3 trees, with favoured access (fingers) at the ends, likedataFingerTree a = Empty | Single a | Deep (Digit a) (FingerTree (Node a)) (Digit a)dataDigit a = One a | Two a a | Three a a a | Four a a a adataNode a = Node2 a a | Node3 a a a

(more examples) and also supports efficient concatenation. To support splitting and searching, we annotate the internal nodes of the tree with values drawn from an application-specific monoid.

- PDF, gzipped PostScript, BibTeX.
- A sequence implementation based on the application discussed in section 4.2
is included as a module
Data.Sequence
in the Glasgow Haskell Compiler and other Haskell implementations.
*Note:*The class`Reduce`in the paper is replaced by the class Foldable. - The fingertree package is a generic finger tree structure, for use as a base for various container types.

*Purely Functional Data Structures*, Chris Okasaki. Cambridge University Press, 1998. A wonderful book presenting general techniques for designing functional data structures, with a wealth of applications. Finger trees can be viewed as an extension of the implicit deques discussed in section 11.1 of the book:

Finger trees result from two extensions of this structure:**data**ImplicitDeque a = Empty | Single a | Deep (Digit a) (ImplicitDeque (a, a)) (Digit a)**data**Digit a = One a | Two a a | Three a a a- Replacing pairs with 2-3 nodes gives sufficient flexibility to
support efficient concatenation.
(To preserve constant-time deque operations,
`Digit`must be expanded to`Four`.) - Annotating internal nodes with a monoid allows efficient splitting.

- Replacing pairs with 2-3 nodes gives sufficient flexibility to
support efficient concatenation.
(To preserve constant-time deque operations,
- Other implementations of persistent deques with concatenation:
- H. Kaplan and R. E. Tarjan.
Purely functional representations of catenable sorted lists,
In
*Proceedings of the 28th Annual ACM Symposium on Theory of Computing*, pages 202–211. ACM Press, 1996. A more complex structure achieving the same bounds, but in the worst case. They also sketch a variant that is claimed to achieve doubly logarithmic time for concatenation. - H. Kaplan and R. E. Tarjan.
Purely Functional, Real-Time Deques with Catenation,
*JACM*, 46(5):577–603, 1999. A refinement, with worst-case constant-time deque operations and concatenation. - A further refinement by Radu Mihaesau and Robert Tarjan (2003).

- H. Kaplan and R. E. Tarjan.
Purely functional representations of catenable sorted lists,
In
- Tutorials on fingertrees in blog posts by apfelmus, Edward Kmett, Tommy McGuire and Andrew Gibiansky.
- Implementations in other languages: C#, Clojure, Coq, Humus, Java, Scala and Isabelle/HOL.