This module provides access to all of the internals of the
DUAL-tree implementation. Depend on the internals at your own
risk! For a safe public API (and complete documentation), see
Data.Tree.DUAL.

The main things exported by this module which are not exported from
Data.Tree.DUAL are two extra types used in the implementation of
DUALTree, along with functions for manipulating them. A type of
non-empty trees, DUALTreeNE, is defined, as well as the type
DUALTreeU which represents a non-empty tree paired with a cached
u annotation. DUALTreeNE and DUALTreeU are mutually
recursive, so that recursive tree nodes are interleaved with cached
u annotations. DUALTree is defined by just wrapping
DUALTreeU in Option. This method has the advantage that the
type system enforces the invariant that there is only one
representation for the empty tree. It also allows us to get away
with only Semigroup constraints in many places.

Rose (n-ary) trees with both upwards- (i.e. cached) and
downwards-traveling (i.e. accumulating) monoidal annotations.
Abstractly, a DUALTree is a rose (n-ary) tree with data (of type
l) at leaves, data (of type a) at internal nodes, and two
types of monoidal annotations, one (of type u) travelling
"up" the tree and one (of type d) traveling "down". See
the documentation at the top of this file for full details.

Semigroup. DUALTreeNEs form a semigroup where (<>)
corresponds to adjoining two trees under a common parent root,
with sconcat specialized to put all the trees under a single
parent. Note that this does not satisfy associativity up to
structural equality, but only up to observational equivalence
under flatten. Technically using foldDUAL directly enables
one to observe the difference, but it is understood that
foldDUAL should be used only in ways such that reassociation
of subtrees "does not matter".

Fold for DUAL-trees. It is given access to the internal and leaf
data, and the accumulated d values at each leaf. It is also
allowed to replace "u-only" leaves with a constant value. In
particular, however, it is not given access to any of the u
annotations, the idea being that those are used only for
constructing trees. It is also not given access to d values
as they occur in the tree, only as they accumulate at leaves. If
you do need access to u or d values, you can duplicate the
values you need in the internal data nodes.