Purely Functional, Real-Time Deques with Catenation (Kaplan & Tarjan)
See the codePurely Functional, Real-Time Deques with Catenation [284ko postscript]
by Haim Kaplan and Robert E. Tarjan
journal of the ACM 31:11-16 (1999) 1709-1723 https://doi.org/10.1145/324133.324139
Following the paper, this library provides 4 implementations of double-ended queues which let you push, pop and append elements at both ends of an ordered collection in worst-case constant time (strict! not amortized) :
| Module | cons | uncons | snoc | unsnoc | append | rev | nth |
|---|---|---|---|---|---|---|---|
| Dequeue | O(1) | O(1) | O(1) | O(1) | :no_entry_sign: | O(1) | O(log min(i, N-i)) |
| Steque | O(1) | O(1) | O(1) | :no_entry_sign: | O(1) | :no_entry_sign: | :no_entry_sign: |
| Deck | O(1) | O(1) | O(1) | O(1) | O(1) | :no_entry_sign: | :no_entry_sign: |
| Deckrev | O(1) | O(1) | O(1) | O(1) | O(1) | O(1) | :no_entry_sign: |
Check out the online documentation for the full interface -- which should be mostly compatible with OCaml's standard List module.
Even though the algorithmic complexity is great, these deques add a significant overhead when compared to lists:
| List | Dequeue | Steque | Deck | Deckrev | |
|---|---|---|---|---|---|
cons | 1x | 1.5x | 1.6x | 1.6x | 2.5x |
uncons | 1x | 13x | 13x | 19x | 22x |
fold_left | 1x | 4.5x | 4.5x | 4.5x | 11.1x |

Example applications include:
O(1) rather than O(length traversed). Such a zipper is a
prerequisite for Brodal's Fast Join-trees and the Functional Link-Cut
trees of Erik Demaine.None of this code would have been possible without the fantastic support for GADTs in OCaml. The invariants are encoded inside each datatypes: the algorithms then follow, guided by the type checker and the lack of recursion. As this does not result in the most readable code, you should read the paper if you want to understand the big ideas:
O(1) fingers
inside a purely functional treeThe core types and algorithms described in the paper can be found in the
src/*_internal.ml files.
41 commits
1 commits
OCaml
99.3%
Purely Functional, Real-Time Deques with Catenation (Kaplan & Tarjan)
See the codePurely Functional, Real-Time Deques with Catenation [284ko postscript]
by Haim Kaplan and Robert E. Tarjan
journal of the ACM 31:11-16 (1999) 1709-1723 https://doi.org/10.1145/324133.324139
Following the paper, this library provides 4 implementations of double-ended queues which let you push, pop and append elements at both ends of an ordered collection in worst-case constant time (strict! not amortized) :
| Module | cons | uncons | snoc | unsnoc | append | rev | nth |
|---|---|---|---|---|---|---|---|
| Dequeue | O(1) | O(1) | O(1) | O(1) | :no_entry_sign: | O(1) | O(log min(i, N-i)) |
| Steque | O(1) | O(1) | O(1) | :no_entry_sign: | O(1) | :no_entry_sign: | :no_entry_sign: |
| Deck | O(1) | O(1) | O(1) | O(1) | O(1) | :no_entry_sign: | :no_entry_sign: |
| Deckrev | O(1) | O(1) | O(1) | O(1) | O(1) | O(1) | :no_entry_sign: |
Check out the online documentation for the full interface -- which should be mostly compatible with OCaml's standard List module.
Even though the algorithmic complexity is great, these deques add a significant overhead when compared to lists:
| List | Dequeue | Steque | Deck | Deckrev | |
|---|---|---|---|---|---|
cons | 1x | 1.5x | 1.6x | 1.6x | 2.5x |
uncons | 1x | 13x | 13x | 19x | 22x |
fold_left | 1x | 4.5x | 4.5x | 4.5x | 11.1x |

Example applications include:
O(1) rather than O(length traversed). Such a zipper is a
prerequisite for Brodal's Fast Join-trees and the Functional Link-Cut
trees of Erik Demaine.None of this code would have been possible without the fantastic support for GADTs in OCaml. The invariants are encoded inside each datatypes: the algorithms then follow, guided by the type checker and the lack of recursion. As this does not result in the most readable code, you should read the paper if you want to understand the big ideas:
O(1) fingers
inside a purely functional treeThe core types and algorithms described in the paper can be found in the
src/*_internal.ml files.
41 commits
1 commits
OCaml
99.3%