----------------------------------------------------------------------------- -- | -- Module : Data.LCRSTree -- Copyright : (c) Pedro Rodriguez Tavarez -- License : BSD3-style (see LICENSE) -- -- Maintainer : Pedro Rodriguez Tavarez -- Stability : unstable -- Portability : unportable -- ------------------------------------------------------------------------------- module Data.LCRSTree where -- Do this in order to avoid unused imports in GHC 7.10 and over without -- needing cpp import Data.Foldable as F import Data.Tree (Tree) import qualified Data.Tree as T -- | A Left-child-right-sibling tree. data LCRSTree n = Empty | Leaf n (LCRSTree n) | Node n (LCRSTree n) (LCRSTree n) deriving (Show, Eq) -- | Functor instance instance Functor LCRSTree where fmap _ Empty = Empty fmap f (Leaf a s) = Leaf (f a) (fmap f s) fmap f (Node n c s) = Node (f n) (fmap f c) (fmap f s) instance Foldable LCRSTree where foldr _ z Empty = z foldr f z (Leaf n s) = F.foldr f (f n z) s foldr f z (Node n c s) = let v = F.foldr f (f n z) c in F.foldr f v s -- | Return the depth of the tree. This means the depth of the longest -- branch lcrsDepth :: Integral i => LCRSTree n -> i lcrsDepth = depth 0 where depth i Empty = i depth i (Leaf _ s) = depth i s depth i (Node _ c s) = let lDepth = depth (i + 1) c rDepth = depth i s in max lDepth rDepth -- | Convert a 'Tree' into a 'LCRSTree' fromRoseTree :: Tree n -> LCRSTree n fromRoseTree t = mkWithS t [] where mkWithS (T.Node n []) ss = Leaf n $ siblings ss mkWithS (T.Node n ch) ss = let mkN = case ch of [] -> Leaf n (c:cs) -> Node n (mkWithS c cs) in mkN $ siblings ss siblings [] = Empty siblings (c:cs) = mkWithS c cs -- | Convert a 'LCRSTree' into a 'Tree' -- -- This function fails if a non-top 'Node' is passed. A non-top node is a node -- @Node n c s@ where @s /= Empty@. toRoseTree :: LCRSTree n -> Tree n toRoseTree (Node topN topC Empty) = T.Node topN (collectS topC) where collectS Empty = [] collectS (Leaf a s) = T.Node a [] : collectS s collectS (Node n c s) = T.Node n (collectS c) : collectS s toRoseTree _ = error "fromLCRSTree: non-top node passed"