1 {-# LANGUAGE BangPatterns #-}
2 {-# LANGUAGE FlexibleInstances #-}
3 {-# LANGUAGE OverloadedStrings #-}
4 module Data.TreeSeq.Strict where
6 import Control.Applicative (Applicative(..))
7 import Control.Monad (Monad(..))
9 import Data.Eq (Eq(..))
10 import Data.Foldable (Foldable(..))
11 import Data.Foldable (foldr)
12 import Data.Function (($), (.))
13 import Data.Functor (Functor(..), (<$>))
14 import Data.Monoid (Monoid(..))
15 import Data.Ord (Ord(..))
16 import Data.Semigroup (Semigroup(..))
17 import Data.Sequence (Seq, ViewL(..))
18 import Data.Traversable (Traversable(..))
19 import Text.Show (Show(..))
20 import qualified Data.List as List
21 import qualified Data.Sequence as Seq
22 import qualified Data.Text.Lazy as TL
27 , subTrees :: !(Trees a)
29 deriving (Eq, Ord, Show)
30 instance Functor Tree where
31 fmap f (Tree a ts) = Tree (f a) (fmap (fmap f) ts)
32 instance Applicative Tree where
33 pure a = Tree a mempty
34 Tree f tfs <*> ta@(Tree a tas) =
35 Tree (f a) (fmap (f <$>) tas <> fmap (<*> ta) tfs)
36 instance Monad Tree where
39 Tree a' (ts' <> fmap (>>= f) ts)
40 where Tree a' ts' = f a
41 instance Foldable Tree where
42 foldMap f (Tree a ts) = f a `mappend` foldMap (foldMap f) ts
43 instance Traversable Tree where
44 traverse f (Tree a ts) = Tree <$> f a <*> traverse (traverse f) ts
45 sequenceA (Tree a ts) = Tree <$> a <*> traverse sequenceA ts
48 tree0 a = Tree a mempty
50 isTree0 :: Tree a -> Bool
51 isTree0 (Tree _ ts) = null ts
53 isTreeN :: Tree a -> Bool
54 isTreeN (Tree _ ts) = not (null ts)
57 mapWithNode :: (Maybe k -> a -> b) -> Tree k a -> Tree k b
58 mapWithNode = go Nothing
60 go _k f (Tree k ts) = Tree k (go (Just k) f <$> ts)
61 go k f (Tree0 a) = Tree0 (f k a)
63 mapAlsoNode :: (k -> l) -> (Maybe k -> a -> b) -> Tree k a -> Tree l b
64 mapAlsoNode fk fv = go Nothing
66 go _k (Tree k ts) = Tree (fk k) $ go (Just k) <$> ts
67 go k (Tree0 a) = Tree0 (fv k a)
69 traverseWithNode :: Applicative f => (Maybe k -> a -> f b) -> Tree k a -> f (Tree k b)
70 traverseWithNode = go Nothing
72 go _p f (Tree k ts) = Tree k <$> traverse (go (Just k) f) ts
73 go p f (Tree0 a) = Tree0 <$> f p a
75 foldlWithTree :: (b -> Tree k a -> b) -> b -> Tree k a -> b
78 Tree _k ts -> foldl' (foldlWithTree f) (f b t) ts
81 bindTree :: Tree k a -> (Tree k a -> Tree l b) -> Tree l b
88 Tree l ls -> Tree l $ ls <> ((`bindTree` f) <$> ks)
90 bindTrees :: Tree k a -> (Tree k a -> Trees l b) -> Trees l b
97 Tree0 b -> Seq.singleton $ Tree0 b
98 Tree l ls -> pure $ Tree l $ ls <> (ks >>= (`bindTrees` f))
100 joinTrees :: Trees k (Trees k a) -> Trees k a
104 Tree k ks -> Seq.singleton $ Tree k $ joinTrees ks
108 type Trees a = Seq (Tree a)
111 newtype Pretty a = Pretty a
112 instance Show a => Show (Pretty (Trees a)) where
113 show (Pretty t) = TL.unpack $ prettyTrees t
114 instance Show a => Show (Pretty (Tree a)) where
115 show (Pretty t) = TL.unpack $ prettyTree t
117 prettyTree :: Show a => Tree a -> TL.Text
118 prettyTree = TL.unlines . pretty
120 prettyTrees :: Show a => Trees a -> TL.Text
121 prettyTrees = foldr (\t acc -> prettyTree t <> "\n" <> acc) ""
123 pretty :: Show a => Tree a -> [TL.Text]
124 pretty (Tree a ts0) = TL.pack (show a) : prettySubTrees ts0
129 t:<ts | Seq.null ts -> "|" : shift "`- " " " (pretty t)
130 | otherwise -> "|" : shift "+- " "| " (pretty t) <> prettySubTrees ts
131 shift first other = List.zipWith (<>) (first : List.repeat other)