#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
#endif
module Data.Semigroup.Applicative
    ( Traversal(..)
    , Ap(..)
    ) where
import Control.Applicative
import Data.Monoid (Monoid(..))
import Data.Semigroup (Semigroup(..))
import Data.Semigroup.Reducer (Reducer(..))
newtype Traversal f = Traversal { getTraversal :: f () }
instance Applicative f => Semigroup (Traversal f) where
  Traversal a <> Traversal b = Traversal (a *> b)
instance Applicative f => Monoid (Traversal f) where
  mempty = Traversal (pure ())
  Traversal a `mappend` Traversal b = Traversal (a *> b)
instance Applicative f => Reducer (f a) (Traversal f) where
  unit = Traversal . (() <$)
  a `cons` Traversal b = Traversal (a *> b)
  Traversal a `snoc` b = Traversal (() <$ (a *> b))
snocTraversal :: Reducer (f ()) (Traversal f) => Traversal f -> f () -> Traversal f
snocTraversal a = (<>) a . Traversal
newtype Ap f m = Ap { getApp :: f m }
  deriving (Functor,Applicative)
instance (Applicative f, Semigroup m) => Semigroup (Ap f m) where
  (<>) = liftA2 (<>)
instance (Applicative f, Monoid m) => Monoid (Ap f m) where
  mempty = pure mempty
  mappend = liftA2 mappend
instance (Applicative f, Reducer c m) => Reducer (f c) (Ap f m) where
  unit = fmap unit . Ap