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

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Data.Semigroup.MonadPlus
    -- Copyright   :  (c) Edward Kmett 2009-2011
    -- License     :  BSD-style
    -- Maintainer  :  ekmett@gmail.com
    -- Stability   :  experimental
    -- Portability :  non-portable (MPTCs)
    --
    -- A semigroup for working with instances of 'MonadPlus'
    --
    -----------------------------------------------------------------------------

    module Data.Semigroup.MonadPlus
        ( MonadSum(..)
        ) where

    import Control.Applicative (Alternative(..))
    import Control.Monad (MonadPlus(..))
    import Data.Semigroup.Reducer (Reducer(..))

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

    #if !(MIN_VERSION_base(4,11,0))
    import Data.Semigroup (Semigroup(..))
    #endif

    -- | A 'MonadSum' turns any 'MonadPlus' instance into a 'Monoid'.

    newtype MonadSum f a = MonadSum { forall (f :: * -> *) a. MonadSum f a -> f a
    getMonadSum :: f a }
      deriving ((forall a b. (a -> b) -> MonadSum f a -> MonadSum f b)
    -> (forall a b. a -> MonadSum f b -> MonadSum f a)
    -> Functor (MonadSum f)
    forall a b. a -> MonadSum f b -> MonadSum f a
    forall a b. (a -> b) -> MonadSum f a -> MonadSum f b
    forall (f :: * -> *) a b.
    Functor f =>
    a -> MonadSum f b -> MonadSum f a
    forall (f :: * -> *) a b.
    Functor f =>
    (a -> b) -> MonadSum f a -> MonadSum f b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall (f :: * -> *) a b.
    Functor f =>
    (a -> b) -> MonadSum f a -> MonadSum f b
    fmap :: forall a b. (a -> b) -> MonadSum f a -> MonadSum f b
    $c<$ :: forall (f :: * -> *) a b.
    Functor f =>
    a -> MonadSum f b -> MonadSum f a
    <$ :: forall a b. a -> MonadSum f b -> MonadSum f a
    Functor,Functor (MonadSum f)
    Functor (MonadSum f) =>
    (forall a. a -> MonadSum f a)
    -> (forall a b.
        MonadSum f (a -> b) -> MonadSum f a -> MonadSum f b)
    -> (forall a b c.
        (a -> b -> c) -> MonadSum f a -> MonadSum f b -> MonadSum f c)
    -> (forall a b. MonadSum f a -> MonadSum f b -> MonadSum f b)
    -> (forall a b. MonadSum f a -> MonadSum f b -> MonadSum f a)
    -> Applicative (MonadSum f)
    forall a. a -> MonadSum f a
    forall a b. MonadSum f a -> MonadSum f b -> MonadSum f a
    forall a b. MonadSum f a -> MonadSum f b -> MonadSum f b
    forall a b. MonadSum f (a -> b) -> MonadSum f a -> MonadSum f b
    forall a b c.
    (a -> b -> c) -> MonadSum f a -> MonadSum f b -> MonadSum f c
    forall (f :: * -> *).
    Functor f =>
    (forall a. a -> f a)
    -> (forall a b. f (a -> b) -> f a -> f b)
    -> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
    -> (forall a b. f a -> f b -> f b)
    -> (forall a b. f a -> f b -> f a)
    -> Applicative f
    forall (f :: * -> *). Applicative f => Functor (MonadSum f)
    forall (f :: * -> *) a. Applicative f => a -> MonadSum f a
    forall (f :: * -> *) a b.
    Applicative f =>
    MonadSum f a -> MonadSum f b -> MonadSum f a
    forall (f :: * -> *) a b.
    Applicative f =>
    MonadSum f a -> MonadSum f b -> MonadSum f b
    forall (f :: * -> *) a b.
    Applicative f =>
    MonadSum f (a -> b) -> MonadSum f a -> MonadSum f b
    forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> MonadSum f a -> MonadSum f b -> MonadSum f c
    $cpure :: forall (f :: * -> *) a. Applicative f => a -> MonadSum f a
    pure :: forall a. a -> MonadSum f a
    $c<*> :: forall (f :: * -> *) a b.
    Applicative f =>
    MonadSum f (a -> b) -> MonadSum f a -> MonadSum f b
    <*> :: forall a b. MonadSum f (a -> b) -> MonadSum f a -> MonadSum f b
    $cliftA2 :: forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> MonadSum f a -> MonadSum f b -> MonadSum f c
    liftA2 :: forall a b c.
    (a -> b -> c) -> MonadSum f a -> MonadSum f b -> MonadSum f c
    $c*> :: forall (f :: * -> *) a b.
    Applicative f =>
    MonadSum f a -> MonadSum f b -> MonadSum f b
    *> :: forall a b. MonadSum f a -> MonadSum f b -> MonadSum f b
    $c<* :: forall (f :: * -> *) a b.
    Applicative f =>
    MonadSum f a -> MonadSum f b -> MonadSum f a
    <* :: forall a b. MonadSum f a -> MonadSum f b -> MonadSum f a
    Applicative,Applicative (MonadSum f)
    Applicative (MonadSum f) =>
    (forall a. MonadSum f a)
    -> (forall a. MonadSum f a -> MonadSum f a -> MonadSum f a)
    -> (forall a. MonadSum f a -> MonadSum f [a])
    -> (forall a. MonadSum f a -> MonadSum f [a])
    -> Alternative (MonadSum f)
    forall a. MonadSum f a
    forall a. MonadSum f a -> MonadSum f [a]
    forall a. MonadSum f a -> MonadSum f a -> MonadSum f a
    forall (f :: * -> *).
    Applicative f =>
    (forall a. f a)
    -> (forall a. f a -> f a -> f a)
    -> (forall a. f a -> f [a])
    -> (forall a. f a -> f [a])
    -> Alternative f
    forall (f :: * -> *). Alternative f => Applicative (MonadSum f)
    forall (f :: * -> *) a. Alternative f => MonadSum f a
    forall (f :: * -> *) a.
    Alternative f =>
    MonadSum f a -> MonadSum f [a]
    forall (f :: * -> *) a.
    Alternative f =>
    MonadSum f a -> MonadSum f a -> MonadSum f a
    $cempty :: forall (f :: * -> *) a. Alternative f => MonadSum f a
    empty :: forall a. MonadSum f a
    $c<|> :: forall (f :: * -> *) a.
    Alternative f =>
    MonadSum f a -> MonadSum f a -> MonadSum f a
    <|> :: forall a. MonadSum f a -> MonadSum f a -> MonadSum f a
    $csome :: forall (f :: * -> *) a.
    Alternative f =>
    MonadSum f a -> MonadSum f [a]
    some :: forall a. MonadSum f a -> MonadSum f [a]
    $cmany :: forall (f :: * -> *) a.
    Alternative f =>
    MonadSum f a -> MonadSum f [a]
    many :: forall a. MonadSum f a -> MonadSum f [a]
    Alternative,Applicative (MonadSum f)
    Applicative (MonadSum f) =>
    (forall a b. MonadSum f a -> (a -> MonadSum f b) -> MonadSum f b)
    -> (forall a b. MonadSum f a -> MonadSum f b -> MonadSum f b)
    -> (forall a. a -> MonadSum f a)
    -> Monad (MonadSum f)
    forall a. a -> MonadSum f a
    forall a b. MonadSum f a -> MonadSum f b -> MonadSum f b
    forall a b. MonadSum f a -> (a -> MonadSum f b) -> MonadSum f b
    forall (f :: * -> *). Monad f => Applicative (MonadSum f)
    forall (f :: * -> *) a. Monad f => a -> MonadSum f a
    forall (f :: * -> *) a b.
    Monad f =>
    MonadSum f a -> MonadSum f b -> MonadSum f b
    forall (f :: * -> *) a b.
    Monad f =>
    MonadSum f a -> (a -> MonadSum f b) -> MonadSum f b
    forall (m :: * -> *).
    Applicative m =>
    (forall a b. m a -> (a -> m b) -> m b)
    -> (forall a b. m a -> m b -> m b)
    -> (forall a. a -> m a)
    -> Monad m
    $c>>= :: forall (f :: * -> *) a b.
    Monad f =>
    MonadSum f a -> (a -> MonadSum f b) -> MonadSum f b
    >>= :: forall a b. MonadSum f a -> (a -> MonadSum f b) -> MonadSum f b
    $c>> :: forall (f :: * -> *) a b.
    Monad f =>
    MonadSum f a -> MonadSum f b -> MonadSum f b
    >> :: forall a b. MonadSum f a -> MonadSum f b -> MonadSum f b
    $creturn :: forall (f :: * -> *) a. Monad f => a -> MonadSum f a
    return :: forall a. a -> MonadSum f a
    Monad,Monad (MonadSum f)
    Alternative (MonadSum f)
    (Alternative (MonadSum f), Monad (MonadSum f)) =>
    (forall a. MonadSum f a)
    -> (forall a. MonadSum f a -> MonadSum f a -> MonadSum f a)
    -> MonadPlus (MonadSum f)
    forall a. MonadSum f a
    forall a. MonadSum f a -> MonadSum f a -> MonadSum f a
    forall (f :: * -> *). MonadPlus f => Monad (MonadSum f)
    forall (f :: * -> *). MonadPlus f => Alternative (MonadSum f)
    forall (f :: * -> *) a. MonadPlus f => MonadSum f a
    forall (f :: * -> *) a.
    MonadPlus f =>
    MonadSum f a -> MonadSum f a -> MonadSum f a
    forall (m :: * -> *).
    (Alternative m, Monad m) =>
    (forall a. m a) -> (forall a. m a -> m a -> m a) -> MonadPlus m
    $cmzero :: forall (f :: * -> *) a. MonadPlus f => MonadSum f a
    mzero :: forall a. MonadSum f a
    $cmplus :: forall (f :: * -> *) a.
    MonadPlus f =>
    MonadSum f a -> MonadSum f a -> MonadSum f a
    mplus :: forall a. MonadSum f a -> MonadSum f a -> MonadSum f a
    MonadPlus)

    instance MonadPlus f => Semigroup (MonadSum f a) where
      MonadSum f a
    a <> :: MonadSum f a -> MonadSum f a -> MonadSum f a
    <> MonadSum f a
    b = f a -> MonadSum f a
    forall (f :: * -> *) a. f a -> MonadSum f a
    MonadSum (f a -> f a -> f a
    forall a. f a -> f a -> f a
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    mplus f a
    a f a
    b)

    instance MonadPlus f => Monoid (MonadSum f a) where
      mempty :: MonadSum f a
    mempty = MonadSum f a
    forall a. MonadSum f a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero
    #if !(MIN_VERSION_base(4,11,0))
      MonadSum a `mappend` MonadSum b = MonadSum (mplus a b)
    #endif

    instance MonadPlus f => Reducer (f a) (MonadSum f a) where
      unit :: f a -> MonadSum f a
    unit = f a -> MonadSum f a
    forall (f :: * -> *) a. f a -> MonadSum f a
    MonadSum