Solution (source code)

= Solution

Carry the eventual output tail as an accumulator, thereby avoiding repeated <list concatenation>:

``
abs :: CatList a -> [a]
abs t = flatten t []
  where
    flatten Nil       zs = zs
    flatten (One x)   zs = x : zs
    flatten (Cat l r) zs = flatten l (flatten r zs)
``

The invariant is `flatten t zs = denotation t ++ zs`. It is immediate for `Nil` and `One`; at `Cat`, applying the two induction hypotheses and <associativity> of <list concatenation> proves it. In particular, the empty accumulator gives the required abstraction.

Each <concatenation tree> constructor is processed once, and each `One` emits one result cons. Consequently full production takes \b[$\Theta(m)$ time], where $m$ is the input constructor count, on every tree shape. This is a <difference list> calculation written with an explicit tail, an instance of <linear flattening of a binary tree>. The <call stack> can have depth $m$ for a badly skewed input; a linear time bound does not imply logarithmic stack space.