{-# 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 { MonadSum f a -> f a
getMonadSum :: f a }
  deriving (a -> MonadSum f b -> MonadSum f a
(a -> b) -> MonadSum f a -> MonadSum f b
(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
<$ :: a -> MonadSum f b -> MonadSum f a
$c<$ :: forall (f :: * -> *) a b.
Functor f =>
a -> MonadSum f b -> MonadSum f a
fmap :: (a -> b) -> MonadSum f a -> MonadSum f b
$cfmap :: forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> MonadSum f a -> MonadSum f b
Functor,Functor (MonadSum f)
a -> MonadSum f a
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)
MonadSum f a -> MonadSum f b -> MonadSum f b
MonadSum f a -> MonadSum f b -> MonadSum f a
MonadSum f (a -> b) -> MonadSum f a -> MonadSum f b
(a -> b -> c) -> MonadSum f a -> MonadSum f b -> MonadSum f c
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
<* :: MonadSum f a -> MonadSum f b -> MonadSum f a
$c<* :: forall (f :: * -> *) a b.
Applicative f =>
MonadSum f a -> MonadSum f b -> MonadSum f a
*> :: MonadSum f a -> MonadSum f b -> MonadSum f b
$c*> :: forall (f :: * -> *) a b.
Applicative f =>
MonadSum f a -> MonadSum f b -> MonadSum f b
liftA2 :: (a -> b -> c) -> MonadSum f a -> MonadSum f b -> MonadSum f c
$cliftA2 :: forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> MonadSum f a -> MonadSum f b -> MonadSum f c
<*> :: MonadSum f (a -> b) -> MonadSum f a -> MonadSum f b
$c<*> :: forall (f :: * -> *) a b.
Applicative f =>
MonadSum f (a -> b) -> MonadSum f a -> MonadSum f b
pure :: a -> MonadSum f a
$cpure :: forall (f :: * -> *) a. Applicative f => a -> MonadSum f a
$cp1Applicative :: forall (f :: * -> *). Applicative f => Functor (MonadSum f)
Applicative,Applicative (MonadSum f)
MonadSum f a
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)
MonadSum f a -> MonadSum f a -> MonadSum f a
MonadSum f a -> MonadSum f [a]
MonadSum f a -> MonadSum f [a]
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
many :: MonadSum f a -> MonadSum f [a]
$cmany :: forall (f :: * -> *) a.
Alternative f =>
MonadSum f a -> MonadSum f [a]
some :: MonadSum f a -> MonadSum f [a]
$csome :: forall (f :: * -> *) a.
Alternative f =>
MonadSum f a -> MonadSum f [a]
<|> :: MonadSum f a -> MonadSum f a -> MonadSum f a
$c<|> :: forall (f :: * -> *) a.
Alternative f =>
MonadSum f a -> MonadSum f a -> MonadSum f a
empty :: MonadSum f a
$cempty :: forall (f :: * -> *) a. Alternative f => MonadSum f a
$cp1Alternative :: forall (f :: * -> *). Alternative f => Applicative (MonadSum f)
Alternative,Applicative (MonadSum f)
a -> MonadSum f a
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)
MonadSum f a -> (a -> MonadSum f b) -> MonadSum f b
MonadSum f a -> MonadSum f b -> MonadSum f b
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
return :: a -> MonadSum f a
$creturn :: forall (f :: * -> *) a. Monad f => a -> MonadSum f a
>> :: MonadSum f a -> MonadSum f b -> MonadSum f b
$c>> :: forall (f :: * -> *) a b.
Monad f =>
MonadSum f a -> MonadSum f b -> MonadSum f b
>>= :: MonadSum f a -> (a -> MonadSum f b) -> MonadSum f b
$c>>= :: forall (f :: * -> *) a b.
Monad f =>
MonadSum f a -> (a -> MonadSum f b) -> MonadSum f b
$cp1Monad :: forall (f :: * -> *). Monad f => Applicative (MonadSum f)
Monad,Monad (MonadSum f)
Alternative (MonadSum f)
MonadSum f a
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)
MonadSum f a -> MonadSum f a -> MonadSum f a
forall a. MonadSum f a
forall a. 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
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
mplus :: MonadSum f a -> MonadSum f a -> MonadSum f a
$cmplus :: forall (f :: * -> *) a.
MonadPlus f =>
MonadSum f a -> MonadSum f a -> MonadSum f a
mzero :: MonadSum f a
$cmzero :: forall (f :: * -> *) a. MonadPlus f => MonadSum f a
$cp2MonadPlus :: forall (f :: * -> *). MonadPlus f => Monad (MonadSum f)
$cp1MonadPlus :: forall (f :: * -> *). MonadPlus f => Alternative (MonadSum f)
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 (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 (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