{-# 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 :: forall a b. (a -> b) -> Tree a -> Tree b
fmap a -> b
f (Leaf a
a) = forall a. a -> Tree a
Leaf forall a b. (a -> b) -> a -> b
$ a -> b
f a
a
 fmap a -> b
f (Node Maybe a
ma [Tree a]
ts) = forall a. Maybe a -> [Tree a] -> Tree a
Node (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Maybe a
ma) forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) [Tree a]
ts

instance Foldable Tree where
 foldMap :: forall m a. Monoid m => (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) = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
f Maybe a
ma forall a. Monoid a => a -> a -> a
`mappend` forall a. Monoid a => [a] -> a
mconcat (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (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 :: forall (f :: * -> *) a. Applicative f => Tree (f a) -> f (Tree a)
sequenceA (Leaf f a
fa) = forall a. a -> Tree a
Leaf 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) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a. Maybe a -> [Tree a] -> Tree a
Node (forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA Maybe (f a)
mfa) forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA [Tree (f a)]
ts