    {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE CPP #-}
    #if __GLASGOW_HASKELL__ >= 702
    {-# LANGUAGE Trustworthy #-}
    #endif

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Data.Semigroup.Self
    -- Copyright   :  (c) Edward Kmett 2009
    -- License     :  BSD-style
    -- Maintainer  :  ekmett@gmail.com
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- A simple 'Monoid' transformer that takes a 'Monoid' m and produces a new @m@-Reducer named 'Self' @m@
    --
    -- This is useful when you have a generator that already contains monoidal values or someone supplies
    -- the map to the monoid in the form of a function rather than as a "Reducer" instance. You can just
    -- @'getSelf' . `reduce`@ or @'getSelf' . 'mapReduce' f@ in those scenarios. These behaviors are encapsulated
    -- into the 'fold' and 'foldMap' combinators in "Data.Monoid.Combinators" respectively.
    --
    -----------------------------------------------------------------------------

    module Data.Semigroup.Self
        ( Self(..)
        )  where

    #if __GLASGOW_HASKELL__ < 710
    import Control.Applicative
    import Data.Foldable
    import Data.Traversable
    #endif
    #if !(MIN_VERSION_base(4,11,0))
    import Data.Semigroup
    #endif
    import Data.Semigroup.Foldable
    import Data.Semigroup.Traversable
    import Data.Semigroup.Reducer (Reducer(..))

    newtype Self m = Self { forall m. Self m -> m
    getSelf :: m } deriving (NonEmpty (Self m) -> Self m
    Self m -> Self m -> Self m
    (Self m -> Self m -> Self m)
    -> (NonEmpty (Self m) -> Self m)
    -> (forall b. Integral b => b -> Self m -> Self m)
    -> Semigroup (Self m)
    forall b. Integral b => b -> Self m -> Self m
    forall m. Semigroup m => NonEmpty (Self m) -> Self m
    forall m. Semigroup m => Self m -> Self m -> Self m
    forall m b. (Semigroup m, Integral b) => b -> Self m -> Self m
    forall a.
    (a -> a -> a)
    -> (NonEmpty a -> a)
    -> (forall b. Integral b => b -> a -> a)
    -> Semigroup a
    $c<> :: forall m. Semigroup m => Self m -> Self m -> Self m
    <> :: Self m -> Self m -> Self m
    $csconcat :: forall m. Semigroup m => NonEmpty (Self m) -> Self m
    sconcat :: NonEmpty (Self m) -> Self m
    $cstimes :: forall m b. (Semigroup m, Integral b) => b -> Self m -> Self m
    stimes :: forall b. Integral b => b -> Self m -> Self m
    Semigroup, Semigroup (Self m)
    Self m
    Semigroup (Self m)
    -> Self m
    -> (Self m -> Self m -> Self m)
    -> ([Self m] -> Self m)
    -> Monoid (Self m)
    [Self m] -> Self m
    Self m -> Self m -> Self m
    forall a.
    Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
    forall {m}. Monoid m => Semigroup (Self m)
    forall m. Monoid m => Self m
    forall m. Monoid m => [Self m] -> Self m
    forall m. Monoid m => Self m -> Self m -> Self m
    $cmempty :: forall m. Monoid m => Self m
    mempty :: Self m
    $cmappend :: forall m. Monoid m => Self m -> Self m -> Self m
    mappend :: Self m -> Self m -> Self m
    $cmconcat :: forall m. Monoid m => [Self m] -> Self m
    mconcat :: [Self m] -> Self m
    Monoid)

    instance Semigroup m => Reducer m (Self m) where
      unit :: m -> Self m
    unit = m -> Self m
    forall m. m -> Self m
    Self

    instance Functor Self where
      fmap :: forall a b. (a -> b) -> Self a -> Self b
    fmap a -> b
    f (Self a
    x) = b -> Self b
    forall m. m -> Self m
    Self (a -> b
    f a
    x)

    instance Foldable Self where
      foldMap :: forall m a. Monoid m => (a -> m) -> Self a -> m
    foldMap a -> m
    f (Self a
    x) = a -> m
    f a
    x

    instance Traversable Self where
      traverse :: forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Self a -> f (Self b)
    traverse a -> f b
    f (Self a
    x) = b -> Self b
    forall m. m -> Self m
    Self (b -> Self b) -> f b -> f (Self b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> a -> f b
    f a
    x

    instance Foldable1 Self where
      foldMap1 :: forall m a. Semigroup m => (a -> m) -> Self a -> m
    foldMap1 a -> m
    f (Self a
    x) = a -> m
    f a
    x

    instance Traversable1 Self where
      traverse1 :: forall (f :: * -> *) a b.
    Apply f =>
    (a -> f b) -> Self a -> f (Self b)
    traverse1 a -> f b
    f (Self a
    x) = b -> Self b
    forall m. m -> Self m
    Self (b -> Self b) -> f b -> f (Self b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> a -> f b
    f a
    x