{-# 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 = (w -> (w, w)) -> m w
forall a. (w -> (a, w)) -> m a
forall w (m :: * -> *) a. MonadAccum w m => (w -> (a, w)) -> m a
accum (,w
forall a. Monoid a => a
mempty)
add :: w -> m ()
add w
x = (w -> ((), w)) -> m ()
forall a. (w -> (a, w)) -> m a
forall w (m :: * -> *) a. MonadAccum w m => (w -> (a, w)) -> m a
accum ((w -> ((), w)) -> m ()) -> (w -> ((), w)) -> m ()
forall a b. (a -> b) -> a -> b
$ ((), w) -> w -> ((), w)
forall a b. a -> b -> a
const ((), w
x)
accum :: (w -> (a, w)) -> m a
accum w -> (a, w)
f = m w
forall w (m :: * -> *). MonadAccum w m => m w
look m w -> (w -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
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 w -> m ()
forall w (m :: * -> *). MonadAccum w m => w -> m ()
add w
v m () -> a -> m a
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 = AccumT w Identity w
forall w (m :: * -> *). (Monoid w, Monad m) => AccumT w m w
Accum.look
add :: w -> AccumT w Identity ()
add = w -> AccumT w Identity ()
forall (m :: * -> *) w. Monad m => w -> AccumT w m ()
Accum.add
accum :: forall a. (w -> (a, w)) -> AccumT w Identity a
accum = (w -> (a, w)) -> AccumT w Identity a
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 -> b) -> LiftingAccum t m a -> LiftingAccum t m b)
-> (forall a b. a -> LiftingAccum t m b -> LiftingAccum t m a)
-> Functor (LiftingAccum t m)
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
$cfmap :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
(a -> b) -> LiftingAccum t m a -> LiftingAccum t m b
fmap :: forall a b. (a -> b) -> LiftingAccum t m a -> LiftingAccum t m b
$c<$ :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
a -> LiftingAccum t m b -> LiftingAccum t m a
<$ :: forall a b. a -> LiftingAccum t m b -> LiftingAccum t m a
Functor,
Functor (LiftingAccum t m)
Functor (LiftingAccum t m) =>
(forall a. a -> LiftingAccum t m a)
-> (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 a b.
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m b)
-> (forall a b.
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m a)
-> Applicative (LiftingAccum t m)
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
$cpure :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Applicative (t m) =>
a -> LiftingAccum t m a
pure :: forall a. a -> LiftingAccum t m a
$c<*> :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
LiftingAccum t m (a -> b)
-> LiftingAccum t m a -> LiftingAccum t m b
<*> :: forall a b.
LiftingAccum t m (a -> b)
-> LiftingAccum t m a -> LiftingAccum t m b
$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
liftA2 :: forall a b c.
(a -> b -> c)
-> LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m c
$c*> :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m b
*> :: 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 a
<* :: forall a b.
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m a
Applicative,
Applicative (LiftingAccum t m)
Applicative (LiftingAccum t m) =>
(forall a b.
LiftingAccum t m a
-> (a -> LiftingAccum t m b) -> LiftingAccum t m b)
-> (forall a b.
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m b)
-> (forall a. a -> LiftingAccum t m a)
-> Monad (LiftingAccum t m)
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
$c>>= :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
LiftingAccum t m a
-> (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 -> LiftingAccum t m b -> LiftingAccum t m b
>> :: forall a b.
LiftingAccum t m a -> LiftingAccum t m b -> LiftingAccum t m b
$creturn :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Monad (t m) =>
a -> LiftingAccum t m a
return :: forall a. a -> LiftingAccum t m a
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 = t m w -> LiftingAccum t m w
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
t m a -> LiftingAccum t m a
LiftingAccum (t m w -> LiftingAccum t m w)
-> (m w -> t m w) -> m w -> LiftingAccum t m w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m w -> t m w
forall (m :: * -> *) a. Monad m => m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m w -> LiftingAccum t m w) -> m w -> LiftingAccum t m w
forall a b. (a -> b) -> a -> b
$ m w
forall w (m :: * -> *). MonadAccum w m => m w
look
add :: w -> LiftingAccum t m ()
add w
x = t m () -> LiftingAccum t m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
t m a -> LiftingAccum t m a
LiftingAccum (t m () -> LiftingAccum t m ())
-> (m () -> t m ()) -> m () -> LiftingAccum t m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m () -> t m ()
forall (m :: * -> *) a. Monad m => m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> LiftingAccum t m ()) -> m () -> LiftingAccum t m ()
forall a b. (a -> b) -> a -> b
$ w -> m ()
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 = t m a -> LiftingAccum t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
t m a -> LiftingAccum t m a
LiftingAccum (t m a -> LiftingAccum t m a)
-> (m a -> t m a) -> m a -> LiftingAccum t m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> t m a
forall (m :: * -> *) a. Monad m => m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> LiftingAccum t m a) -> m a -> LiftingAccum t m a
forall a b. (a -> b) -> a -> b
$ (w -> (a, w)) -> m a
forall a. (w -> (a, w)) -> m a
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 (w -> a) -> m w -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m w
forall w (m :: * -> *). MonadAccum w m => m w
look