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.
DUALTree comes with some instances:
Functor, for modifying leaf data. Note that fmap of course cannot alter any
uannotations.Semigroup.
DUALTreeNEs form a semigroup where(<>)corresponds to adjoining two trees under a common parent root, withsconcatspecialized 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".Monoid. The identity is the empty tree.
Instances6Action, Functor, Eq, Show, Semigroup, Monoid
(Semigroup d, Semigroup u, Action d u) => Action (DAct d) (DUALTree d u a l)Defined in dual-tree-0.2.3.4 · Data.Tree.DUAL.InternalApply a
dannotation at the root of a tree. Semantically, alluannotations are transformed by the action ofd, although operationallyactincurs only a constant amount of work.Functor (DUALTree d u a)Defined in dual-tree-0.2.3.4 · Data.Tree.DUAL.Internal(Eq l, Eq u, Eq d, Eq a) => Eq (DUALTree d u a l)Defined in dual-tree-0.2.3.4 · Data.Tree.DUAL.Internal(Show l, Show u, Show d, Show a) => Show (DUALTree d u a l)Defined in dual-tree-0.2.3.4 · Data.Tree.DUAL.Internal(Action d u, Semigroup u) => Semigroup (DUALTree d u a l)Defined in dual-tree-0.2.3.4 · Data.Tree.DUAL.InternalThe
Semigroupinstance is carefully crafted so that sconcat creates a flat, rather than deeply nested, tree. Simply auto-deriving the Semigroup instance produces an sconcat implementation which calls(<>)repeatedly, which is not what we want. Manually definingsconcat = DUALTree . sconcat . fmap unDUALTreeUdoes not even work either, since it ends up using sconcat for Maybe, which still turns into nested calls to(<>).(Semigroup u, Action d u) => Monoid (DUALTree d u a l)Defined in dual-tree-0.2.3.4 · Data.Tree.DUAL.Internal