data-forest 0.1.0.3 → 0.1.0.4
raw patch · 2 files changed
+72/−15 lines, 2 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ Data.Forest: foldForest :: ([(a, b)] -> b) -> Forest a -> b
+ Data.Forest: foldTree :: (a -> [b] -> b) -> Tree a -> b
+ Data.Forest: instance Data.Traversable.Traversable Data.Forest.Forest
+ Data.Forest: instance Data.Traversable.Traversable Data.Forest.Tree
Files
- data-forest.cabal +1/−1
- src/Data/Forest.hs +71/−14
data-forest.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack name: data-forest-version: 0.1.0.3+version: 0.1.0.4 synopsis: A simple multi-way tree data structure. description: In some contexts, forests (collections of zero or more trees) are more important than trees. The /data-forest/ library provides a @Tree@ type much like the one from the popular /containers/ library, but it also provides a @Forest@ type with its own @Functor@ and @Foldable@ instances.
src/Data/Forest.hs view
@@ -5,7 +5,8 @@ -} -{-# LANGUAGE DeriveFoldable, DeriveFunctor, GeneralizedNewtypeDeriving #-}+{-# LANGUAGE DeriveFoldable, DeriveFunctor, DeriveTraversable,+ GeneralizedNewtypeDeriving #-} module Data.Forest (@@ -28,6 +29,10 @@ , subforest , subtrees + -- * Folds+ , foldForest+ , foldTree+ -- * Forest functor -- $functor @@ -35,9 +40,11 @@ import Data.Eq (Eq) import Data.Foldable (Foldable)-import Data.Functor (Functor, fmap)+import Data.Function (($))+import Data.Functor (Functor, (<$>), fmap) import Data.Monoid (Monoid, mempty) import Data.Semigroup (Semigroup)+import Data.Traversable (Traversable) import Prelude (Show) --------------------------------------------------------------------------------@@ -49,7 +56,7 @@ newtype Forest a = Forest { trees :: [Tree a] -- ^ The trees that constitute the forest. }- deriving (Eq, Show, Foldable, Functor, Semigroup, Monoid)+ deriving (Eq, Show, Functor, Foldable, Traversable, Semigroup, Monoid) -- | A tree is defined completely by its 'root' and its 'subforest'. --@@ -60,7 +67,7 @@ , subforest :: Forest a -- ^ The forest containing all descendants -- of the tree's 'root'. }- deriving (Eq, Show, Foldable, Functor)+ deriving (Eq, Show, Functor, Foldable, Traversable) -------------------------------------------------------------------------------- @@ -93,6 +100,55 @@ subtrees :: Tree a -> [Tree a] subtrees t = trees (subforest t) +{- | Catamorphism on forests.++>>>+:{+example :: Forest Char+example = forest+ [ tree 'a' $ leaves "bc"+ , tree 'd' $ forest+ [ leaf 'e'+ , tree 'f' $ leaves "g"+ ]+ ]+:}++>>> foldForest (intercalate ", " . fmap (\(a, b) -> [a] <> " [" <> b <> "]")) example+"a [b [], c []], d [e [], f [g []]]"++-}+foldForest :: ([(a, b)] -> b) -> Forest a -> b+foldForest f =+ go+ where+ go (Forest ts) = f $ (\t -> (root t, go (subforest t))) <$> ts++{- | Catamorphism on trees.++>>>+:{+example :: Tree Char+example = tree 'a' $ forest+ [ tree 'b' $ leaves "cd"+ , tree 'e' $ forest+ [ leaf 'f'+ , tree 'g' $ leaves "h"+ ]+ ]+:}++>>> foldTree (\a bs -> [a] <> " [" <> intercalate ", " bs <> "]") example+"a [b [c [], d []], e [f [], g [h []]]]"++-}+foldTree :: (a -> [b] -> b) -> Tree a -> b+foldTree f =+ go+ where+ go t = f (root t) (go <$> subtrees t)++ -------------------------------------------------------------------------------- {- $setup@@ -100,6 +156,7 @@ >>> import Prelude >>> import Data.Char >>> import Data.Foldable+>>> import Data.Function >>> import Data.List >>> import Data.Semigroup @@ -138,20 +195,20 @@ >>> :{-printCharForest = putStrLn . showForest+showCharForest f =+ intercalate ", " (showCharTree <$> trees f) where- showForest f = intercalate ", " (fmap showTree (trees f))- showTree t = case trees (subforest t) of- [] -> [root t]- [t'] -> [root t] <> ": " <> showTree t'- ts -> [root t] <> ": (" <> showForest (subforest t) <> ")"+ showCharTree t = case trees (subforest t) of+ [] -> [root t]+ [t'] -> [root t] <> ": " <> showCharTree t'+ ts -> [root t] <> ": (" <> showCharForest (subforest t) <> ")" :} ->>> printCharForest example-a: (b, c), d: (e, f: g)+>>> showCharForest example+"a: (b, c), d: (e, f: g)" ->>> printCharForest (fmap toUpper example)-A: (B, C), D: (E, F: G)+>>> showCharForest (fmap toUpper example)+"A: (B, C), D: (E, F: G)" Likewise, 'Forest''s 'Foldable' instance folds over the elements of the forest.