{-# LANGUAGE DeriveGeneric #-} module TreeExtra where import GHC.Generics (Generic) import Control.DeepSeq import Data.Foldable data FTree a = FBranch (a -> a) (FTree a) | FBranches [FTree a] | FLeaf a instance Foldable FTree where foldMap g (FBranch f t) = foldMap (g . f) t foldMap g (FBranches ts) = mconcat $ map (foldMap g) ts foldMap g (FLeaf x) = g x {-# INLINE foldMap #-} instance Functor FTree where fmap g (FBranch f t) = fmap (g . f) t fmap f (FBranches ts) = FBranches $ fmap (fmap f) ts fmap f (FLeaf x) = FLeaf (f x) {-# INLINE fmap #-} {- Tree with values at and only at the leaves. -} data LTree a = LBranches [LTree a] | LLeaf a deriving (Generic) instance NFData a => NFData (LTree a) instance Foldable LTree where foldMap g (LBranches ts) = mconcat $ map (foldMap g) ts foldMap g (LLeaf a) = g a {-# INLINE foldMap #-} foldr _ x (LBranches []) = x --foldr g x (LBranches (t:ts)) = foldr g x t `seq` foldr g (foldr g x t) (LBranches ts) foldr g x (LBranches (t:ts)) = foldr g (foldr g x t) (LBranches ts) --foldr g x (LBranches (t:ts)) = foldr g (foldr g x (LBranches ts)) t foldr g x (LLeaf y) = g y x {-# INLINE foldr #-} foldl' _ x (LBranches []) = x foldl' g x (LBranches (t:ts)) = foldl' g x t `seq` foldl' g (foldl' g x t) (LBranches ts) foldl' g x (LLeaf y) = g x y {-# INLINE foldl' #-} instance Functor LTree where fmap f (LBranches ts) = LBranches $ fmap (fmap f) ts fmap f (LLeaf x) = LLeaf (f x) {-# INLINE fmap #-} data RTree a b = RBranches a [RTree a b] | RLeaf b instance Foldable (RTree a) where foldMap g (RBranches _ ts) = mconcat $ map (foldMap g) ts foldMap g (RLeaf x) = g x {-# INLINE foldMap #-} instance Functor (RTree a) where fmap f (RBranches i ts) = RBranches i $ fmap (fmap f) ts fmap f (RLeaf x) = RLeaf (f x)