{-# LANGUAGE CPP #-}

-- | Tree definition with some class instances.
module Text.LaTeX.Packages.Trees (
   -- * Tree
   Tree (..)
 ) where

#if !MIN_VERSION_base(4,8,0)
import Data.Monoid
import Data.Foldable
import Data.Traversable
#endif
import Control.Applicative

-- | Tree datatype.
data Tree a =
   Leaf a -- ^ Leafs are non-empty.
 | Node (Maybe a) [Tree a] -- ^ Node values are optional.

instance Functor Tree where
 fmap :: (a -> b) -> Tree a -> Tree b
fmap a -> b
f (Leaf a
a) = b -> Tree b
forall a. a -> Tree a
Leaf (b -> Tree b) -> b -> Tree b
forall a b. (a -> b) -> a -> b
$ a -> b
f a
a
 fmap a -> b
f (Node Maybe a
ma [Tree a]
ts) = Maybe b -> [Tree b] -> Tree b
forall a. Maybe a -> [Tree a] -> Tree a
Node ((a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Maybe a
ma) ([Tree b] -> Tree b) -> [Tree b] -> Tree b
forall a b. (a -> b) -> a -> b
$ (Tree a -> Tree b) -> [Tree a] -> [Tree b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> Tree a -> Tree b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) [Tree a]
ts

instance Foldable Tree where
 foldMap :: (a -> m) -> Tree a -> m
foldMap a -> m
f (Leaf a
a) = a -> m
f a
a
 foldMap a -> m
f (Node Maybe a
ma [Tree a]
ts) = (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
f Maybe a
ma m -> m -> m
forall a. Monoid a => a -> a -> a
`mappend` [m] -> m
forall a. Monoid a => [a] -> a
mconcat ((Tree a -> m) -> [Tree a] -> [m]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> m) -> Tree a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
f) [Tree a]
ts)

instance Traversable Tree where
 sequenceA :: Tree (f a) -> f (Tree a)
sequenceA (Leaf f a
fa) = a -> Tree a
forall a. a -> Tree a
Leaf (a -> Tree a) -> f a -> f (Tree a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
fa
 sequenceA (Node Maybe (f a)
mfa [Tree (f a)]
ts) = (Maybe a -> [Tree a] -> Tree a)
-> f (Maybe a) -> f [Tree a] -> f (Tree a)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Maybe a -> [Tree a] -> Tree a
forall a. Maybe a -> [Tree a] -> Tree a
Node (Maybe (f a) -> f (Maybe a)
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA Maybe (f a)
mfa) (f [Tree a] -> f (Tree a)) -> f [Tree a] -> f (Tree a)
forall a b. (a -> b) -> a -> b
$ (Tree (f a) -> f (Tree a)) -> [Tree (f a)] -> f [Tree a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Tree (f a) -> f (Tree a)
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [Tree (f a)]
ts