{-# 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 { Self m -> m
getSelf :: m } deriving (b -> Self m -> Self m
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
stimes :: b -> Self m -> Self m
$cstimes :: forall m b. (Semigroup m, Integral b) => b -> Self m -> Self m
sconcat :: NonEmpty (Self m) -> Self m
$csconcat :: forall m. Semigroup m => NonEmpty (Self m) -> Self m
<> :: Self m -> Self m -> Self m
$c<> :: forall m. Semigroup m => Self m -> 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
mconcat :: [Self m] -> Self m
$cmconcat :: forall m. Monoid m => [Self m] -> Self m
mappend :: Self m -> Self m -> Self m
$cmappend :: forall m. Monoid m => Self m -> Self m -> Self m
mempty :: Self m
$cmempty :: forall m. Monoid m => Self m
$cp1Monoid :: forall m. Monoid m => Semigroup (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 :: (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 :: (a -> m) -> Self a -> m
foldMap a -> m
f (Self a
x) = a -> m
f a
x

instance Traversable Self where
  traverse :: (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 :: (a -> m) -> Self a -> m
foldMap1 a -> m
f (Self a
x) = a -> m
f a
x

instance Traversable1 Self where
  traverse1 :: (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