An individual can have any number of children, so use a rose tree, with one list of child trees at each root:
data DescendantTree = Desc Person [DescendantTree]
deriving Show
descendants :: Database -> Person -> DescendantTree
descendants db p = Desc p (map (descendants db) (children db p))The root records
p, its immediate child trees record children db p, and recursion repeats the same construction at each generation. An individual with no recorded children produces Desc p []. For a finite database whose parent-child directed graph is acyclic, every recursive descent advances along a path that cannot revisit a vertex, so the construction terminates. On inconsistent cyclic records it can unfold indefinitely; finiteness of the database alone is insufficient for termination.A list unfold needs an explicit state describing the unvisited work. Use a list of pending rose trees, with the next tree first. Emit that tree's root label, and replace it by its children followed by the remaining pending trees:
dftU :: RTree a -> [a]
dftU t = unfold null label advance [t]
where
label :: [RTree a] -> a
label (Node x _ : _) = x
advance :: [RTree a] -> [RTree a]
advance (Node _ children : rest) = children ++ restThe boxed state transition is , with output . The stopping test prevents either helper from being applied to
[].The loop invariant is that concatenating the depth-first traversals of the pending trees gives exactly the unproduced output. Removing the next root emits its first label; replacing that tree by its children preserves the remainder of that preorder traversal. Adding children at the front realizes an explicit-stack depth-first tree traversal; placing them at the end would give a different visiting order. The first states for the source example have roots
[1], [2,5,6], [3,4,5,6], [4,5,6], [5,6], [6], [7], [].The child results supplied by the tree fold are already their depth-first traversals. Prepend the current label to their list concatenation:
dftF :: RTree a -> [a]
dftF = foldRTree visit
where
visit :: a -> [[a]] -> [a]
visit x childLists = x : concat childListsThus . Substituting the equation for the tree fold gives exactly the recursive preorder traversal equation from part (i), proving equality by structural induction on a finite rose tree.
dft :: RTree a -> [a]
dft (Node x ts) = x : concatMap dft tsThis is preorder traversal:The Haskell concatMap function preserves child order and finishes each child subtree before moving to the next. A leaf yields its singleton label; the source example yields
[1,2,3,4,5,6,7].A tree fold first folds every child rose tree, then supplies the resulting list and the current label to the combining function:The label type
foldRTree :: (a -> [b] -> b) -> RTree a -> b
foldRTree f (Node x children) =
f x (map (foldRTree f) children)a and result type b are independent, so the polymorphic type needs no class constraint. With f x ys = x + sum ys, every label is counted exactly once; the illustrated labels sum to 28.Compute either the common depth of the leaves of a rooted tree, or failure when the depths differ. A tree fold can return a A leaf has depth zero. An internal vertex has equally deep leaves exactly when every child rose tree is perfect and their returned depths agree; adding one accounts for the edge to each child. This proves the stated meaning of the result by structural induction. In particular, unary branching is allowed, and a single leaf is perfect.
Maybe Integer: Just h means that the rose tree is a perfect rose tree with all leaves at depth relative to its root; Nothing means it is not perfect.perfect :: RTree a -> Bool
perfect t =
case foldRTree step t of
Nothing -> False
Just _ -> True
where
step :: a -> [Maybe Integer] -> Maybe Integer
step _ [] = Just 0
step _ (Nothing : _) = Nothing
step _ (Just h : hs)
| all (== Just h) hs = Just (h + 1)
| otherwise = Nothingperfect returns precisely the required Boolean. Its time complexity is linear in the number of vertices, assuming unit-cost depth arithmetic; labels are never compared or evaluated.Use For a nonempty forest, write its first rose tree as Thus the recursive Haskell definition isThe nested call supplies the continuation of the preorder traversal as a suffix. Each label is emitted once, without repeated list concatenation of an already flattened subtree. For a finite forest, constructing its entire contribution takes linear time in its number of vertices, without traversing the supplied suffix
concat [] = [], concat (ys:yss) = ys ++ concat yss, the corresponding equations for map, associativity of list concatenation, and (r:ys) ++ zs = r:(ys ++ zs). For an empty forest,flatten2 [] xs
= concat (map flatten []) ++ xs
= [] ++ xs
= xsNode r children:flatten2 (Node r children : trees) xs
= (flatten (Node r children) ++ concat (map flatten trees)) ++ xs
= (r : concat (map flatten children))
++ (concat (map flatten trees) ++ xs)
= r : (concat (map flatten children) ++ flatten2 trees xs)
= r : flatten2 children (flatten2 trees xs)flatten2 :: [RTree a] -> [a] -> [a]
flatten2 [] xs = xs
flatten2 (Node r children : trees) xs =
r : flatten2 children (flatten2 trees xs)xs. Perfect rose tree 2026-10-31
A rose tree is perfect when all its leaves of a rooted tree have the same depth. This permits unequal branching counts and unary branches; perfectness alone does not require every internal vertex to have the same number of children. A bottom-up certificate returns
Just 0 at a leaf, Just (h+1) when all child certificates are Just h, and Nothing otherwise. Structural induction proves that a certificate exists exactly when the tree is perfect: all root-to-leaf routes acquire one edge when attached to the new root. Perfect ternary tree 2026-10-31
A full ternary tree whose leaves all have the same depth. At depth there are vertices, so a tree with levels has vertices and leaves, by the finite geometric series formula. For a rose tree representation, recursively flattening children and joining their lists with ordinary list concatenation copies each label once per ancestor. The work is therefore when the complete output is demanded. Passing an already constructed suffix through the recursion instead emits each label once, giving work.
Rose tree 2026-10-31
A rose tree is an ordered rooted tree in which each vertex can have any finite number of children in a rooted tree. A labelled Haskell representation is
data RTree a = Node a [RTree a]. Its tree fold has type (a -> [b] -> b) -> RTree a -> b: recursively fold the children, then combine their results with the current label. Unlike a binary tree, a rose tree has no fixed pair of child positions.