A value-bearing perfect binary tree has size , and the next size is . Suppose two size- trees have at least one smaller tree before them. The portion represented by these trees and that nonempty preceding portion has at least elements. The greedy choice would have used a larger perfect binary tree instead, contradicting the specified representation. Three size- trees are likewise impossible, since . Therefore the only possible repeated size is a pair at the beginning. This is the representation invariant of a skew-binary random-access list.
The empty skew-binary random-access list contains no trees:Both construction of
nil :: List a
nil = List []
null :: List a -> Bool
null (List []) = True
null _ = Falsenil and testing null take constant time.The first tree's root is the first element. Deleting that root either discards a singleton or exposes two equal-sized child trees:For a node of size , both children have size . Their order agrees with the old preorder traversal, and they become the sole permitted initial duplicate. The rest of the forest was no smaller than the old root tree. Thus both operations preserve the representation invariant and take worst-case time on a nonempty skew-binary random-access list.
head :: List a -> a
head (List ((_,Leaf x):_)) = x
head (List ((_,Node x _ _):_)) = x
head (List []) = error "head: empty list"
tail :: List a -> List a
tail (List ((_,Leaf _):ts)) = List ts
tail (List ((w,Node _ l r):ts)) =
let h = w `div` 2 in List ((h,l):(h,r):ts)
tail (List []) = error "tail: empty list" Random-access list 2026-10-24
A persistent list representation supporting positional lookup more efficiently than a conventional linked list. Different implementations trade lookup, insertion and deletion costs; “random-access” does not itself guarantee constant-time indexing. A skew-binary random-access list supports worst-case constant-time front insertion and removal with logarithmic worst-case lookup.