{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-trustworthy-safe #-}
module Control.Monad.Accum
(
MonadAccum (..),
LiftingAccum (..),
looks,
)
where
import Control.Monad.Trans.Accum (AccumT)
import qualified Control.Monad.Trans.Accum as Accum
import Control.Monad.Trans.Class (MonadTrans (lift))
import Control.Monad.Trans.Cont (ContT)
import Control.Monad.Trans.Except (ExceptT)
import Control.Monad.Trans.Identity (IdentityT)
import Control.Monad.Trans.Maybe (MaybeT)
import qualified Control.Monad.Trans.RWS.CPS as CPSRWS
import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS
import qualified Control.Monad.Trans.RWS.Strict as StrictRWS
import Control.Monad.Trans.Reader (ReaderT)
import Control.Monad.Trans.Select (SelectT)
import qualified Control.Monad.Trans.State.Lazy as LazyState
import qualified Control.Monad.Trans.State.Strict as StrictState
import qualified Control.Monad.Trans.Writer.CPS as CPSWriter
import qualified Control.Monad.Trans.Writer.Lazy as LazyWriter
import qualified Control.Monad.Trans.Writer.Strict as StrictWriter
import Data.Functor (($>))
import Data.Functor.Identity (Identity)
import Data.Kind (Type)
class (Monoid w, Monad m) => MonadAccum w m | m -> w where
look :: m w
look = forall w (m :: * -> *) a. MonadAccum w m => (w -> (a, w)) -> m a
accum (,forall a. Monoid a => a
mempty)
add :: w -> m ()
add w
x = forall w (m :: * -> *) a. MonadAccum w m => (w -> (a, w)) -> m a
accum forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
const ((), w
x)
accum :: (w -> (a, w)) -> m a
accum w -> (a, w)
f = forall w (m :: * -> *). MonadAccum w m => m w
look forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \w
acc -> let (a
res, w
v) = w -> (a, w)
f w
acc in forall w (m :: * -> *). MonadAccum w m => w -> m ()
add w
v forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> a
res
{-# MINIMAL accum | look, add #-}
instance (Monoid w) => MonadAccum w (AccumT w Identity) where
look :: AccumT w Identity w
look = forall w (m :: * -> *). (Monoid w, Monad m) => AccumT w m w
Accum.look
add :: w -> AccumT w Identity ()
add = forall (m :: * -> *) w. Monad m => w -> AccumT w m ()
Accum.add
accum :: forall a. (w -> (a, w)) -> AccumT w Identity a
accum = forall (m :: * -> *) w a. Monad m => (w -> (a, w)) -> AccumT w m a
Accum.accum
deriving via
(LiftingAccum MaybeT m)
instance
(MonadAccum w m) =>
MonadAccum w (MaybeT m)
deriving via
(LiftingAccum (ContT r) m)
instance
(MonadAccum w m) =>
MonadAccum w (ContT r m)
deriving via
(LiftingAccum (ExceptT e) m)
instance
(MonadAccum w m) =>
MonadAccum w (ExceptT e m)
deriving via
(LiftingAccum IdentityT m)
instance
(MonadAccum w m) =>
MonadAccum w (IdentityT m)
deriving via
(LiftingAccum (CPSRWS.RWST r w s) m)
instance
(MonadAccum w' m) =>
MonadAccum w' (CPSRWS.RWST r w s m)
deriving via
(LiftingAccum (LazyRWS.RWST r w s) m)
instance
(MonadAccum w' m, Monoid w) =>
MonadAccum w' (LazyRWS.RWST r w s m)
deriving via
(LiftingAccum (StrictRWS.RWST r w s) m)
instance
(MonadAccum w' m, Monoid w) =>
MonadAccum w' (StrictRWS.RWST r w s m)
deriving via
(LiftingAccum (ReaderT r) m)
instance
(MonadAccum w m) =>
MonadAccum w (ReaderT r m)
deriving via
(LiftingAccum (SelectT r) m)
instance
(MonadAccum w m) =>
MonadAccum w (SelectT r m)
deriving via
(LiftingAccum (LazyState.StateT s) m)
instance
(MonadAccum w m) =>
MonadAccum w (LazyState.StateT s m)
deriving via
(LiftingAccum (StrictState.StateT s) m)
instance
(MonadAccum w m) =>
MonadAccum w (StrictState.StateT s m)
deriving via
(LiftingAccum (CPSWriter.WriterT w) m)
instance
(MonadAccum w' m) =>
MonadAccum w' (CPSWriter.WriterT w m)
deriving via
(LiftingAccum (LazyWriter.WriterT w) m)
instance
(MonadAccum w' m, Monoid w) =>
MonadAccum w' (LazyWriter.WriterT w m)
deriving via
(LiftingAccum (StrictWriter.WriterT w) m)
instance
(MonadAccum w' m, Monoid w) =>
MonadAccum w' (StrictWriter.WriterT w m)
newtype LiftingAccum (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) (a :: Type)
= LiftingAccum (t m a)
deriving
(
forall a b. a -> LiftingAccum t m b -> LiftingAccum t m a
forall a b. (a -> b) -> LiftingAccum t m a -> LiftingAccum t m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
a -> LiftingAccum t m b -> LiftingAccum t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
(a -> b) -> LiftingAccum t m a -> LiftingAccum t m b
<$ :: forall a b. a -> LiftingAccum t m b -> LiftingAccum t m a
$c<$ :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
a -> LiftingAccum t m b -> LiftingAccum t m a
fmap :: forall a b. (a -> b) -> LiftingAccum t m a -> LiftingAccum t m b
$cfmap :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
(a -> b) -> LiftingAccum t m a -> LiftingAccum t m b
Functor,
forall a. a -> LiftingAccum t m a
forall a b.
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m a
forall a b.
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m b
forall a b.
LiftingAccum t m (a -> b)
-> LiftingAccum t m a -> LiftingAccum t m b
forall a b c.
(a -> b -> c)
-> LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m 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 {t :: (* -> *) -> * -> *} {m :: * -> *}.
Applicative (t m) =>
Functor (LiftingAccum t m)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Applicative (t m) =>
a -> LiftingAccum t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m b
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
LiftingAccum t m (a -> b)
-> LiftingAccum t m a -> LiftingAccum t m b
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b c.
Applicative (t m) =>
(a -> b -> c)
-> LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m c
<* :: forall a b.
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m a
$c<* :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m a
*> :: forall a b.
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m b
$c*> :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m b
liftA2 :: forall a b c.
(a -> b -> c)
-> LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m c
$cliftA2 :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b c.
Applicative (t m) =>
(a -> b -> c)
-> LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m c
<*> :: forall a b.
LiftingAccum t m (a -> b)
-> LiftingAccum t m a -> LiftingAccum t m b
$c<*> :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
LiftingAccum t m (a -> b)
-> LiftingAccum t m a -> LiftingAccum t m b
pure :: forall a. a -> LiftingAccum t m a
$cpure :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Applicative (t m) =>
a -> LiftingAccum t m a
Applicative,
forall a. a -> LiftingAccum t m a
forall a b.
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m b
forall a b.
LiftingAccum t m a
-> (a -> LiftingAccum t m b) -> LiftingAccum t m 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
forall {t :: (* -> *) -> * -> *} {m :: * -> *}.
Monad (t m) =>
Applicative (LiftingAccum t m)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Monad (t m) =>
a -> LiftingAccum t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m b
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
LiftingAccum t m a
-> (a -> LiftingAccum t m b) -> LiftingAccum t m b
return :: forall a. a -> LiftingAccum t m a
$creturn :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Monad (t m) =>
a -> LiftingAccum t m a
>> :: forall a b.
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m b
$c>> :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m b
>>= :: forall a b.
LiftingAccum t m a
-> (a -> LiftingAccum t m b) -> LiftingAccum t m b
$c>>= :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
LiftingAccum t m a
-> (a -> LiftingAccum t m b) -> LiftingAccum t m b
Monad
)
via (t m)
instance (MonadTrans t, Monad (t m), MonadAccum w m) => MonadAccum w (LiftingAccum t m) where
look :: LiftingAccum t m w
look = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
t m a -> LiftingAccum t m a
LiftingAccum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall w (m :: * -> *). MonadAccum w m => m w
look
add :: w -> LiftingAccum t m ()
add w
x = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
t m a -> LiftingAccum t m a
LiftingAccum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall w (m :: * -> *). MonadAccum w m => w -> m ()
add w
x
accum :: forall a. (w -> (a, w)) -> LiftingAccum t m a
accum w -> (a, w)
f = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
t m a -> LiftingAccum t m a
LiftingAccum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall w (m :: * -> *) a. MonadAccum w m => (w -> (a, w)) -> m a
accum w -> (a, w)
f
looks ::
forall (a :: Type) (m :: Type -> Type) (w :: Type).
(MonadAccum w m) =>
(w -> a) ->
m a
looks :: forall a (m :: * -> *) w. MonadAccum w m => (w -> a) -> m a
looks w -> a
f = w -> a
f forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall w (m :: * -> *). MonadAccum w m => m w
look