Rose (n-ary) trees with both upwards- (i.e. cached) and
downwards-traveling (i.e. accumulating) monoidal annotations.
This is used as the core data structure underlying the diagrams
framework (http://projects.haskell.org/diagrams), but potentially
has other applications as well.

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".

There is also a special type of leaf node which contains only a
u value, and no data. This allows cached u values to be
"modified" by inserting extra annotations.

Branch nodes, containing a list of subtrees.

Internal nodes with a value of type d. d may have an
action on u (see the Action type class, defined in
Data.Monoid.Action from the monoid-extras package).
Semantically speaking, applying a d annotation to a tree
transforms all the u annotations below it by acting on them.
Operationally, however, since the action must be a monoid
homomorphism, applying a d annotation can actually be done in
constant time.

Internal nodes with data values of type a, possibly of a
different type than those in the leaves. These are just "along
for the ride" and are unaffected by u and d annotations.

There are two critical points to note about u and d annotations:

The combined u annotation for an entire tree is always cached
at the root and available in constant (amortized) time.

The mconcat of all the d annotations along the path from
the root to each leaf is available along with the leaf during a
fold operation.

A fold over a DUALTree 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.

DUAL-trees

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.