module Data.Accessor.MonadStatePrivate where

import qualified Data.Accessor.Basic as Accessor
import qualified Control.Monad.Trans.State as State
import qualified Control.Monad.Trans.Class as Trans
import Control.Monad.Trans.State (State, runState, StateT(runStateT), )

-- * accessors in the form of actions in the state monad

set :: Monad m => Accessor.T r a -> a -> StateT r m ()
set :: forall (m :: * -> *) r a. Monad m => T r a -> a -> StateT r m ()
set T r a
f a
x = (r -> r) -> StateT r m ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
State.modify (T r a -> a -> r -> r
forall r a. T r a -> a -> r -> r
Accessor.set T r a
f a
x)

get :: Monad m => Accessor.T r a -> StateT r m a
get :: forall (m :: * -> *) r a. Monad m => T r a -> StateT r m a
get T r a
f = (r -> a) -> StateT r m a
forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
State.gets (T r a -> r -> a
forall r a. T r a -> r -> a
Accessor.get T r a
f)

modify :: Monad m => Accessor.T r a -> (a -> a) -> StateT r m ()
modify :: forall (m :: * -> *) r a.
Monad m =>
T r a -> (a -> a) -> StateT r m ()
modify T r a
f a -> a
g = (r -> r) -> StateT r m ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
State.modify (T r a -> (a -> a) -> r -> r
forall r a. T r a -> (a -> a) -> r -> r
Accessor.modify T r a
f a -> a
g)

{- |
Modify a record element and return its old value.
-}
getAndModify :: Monad m => Accessor.T r a -> (a -> a) -> StateT r m a
getAndModify :: forall (m :: * -> *) r a.
Monad m =>
T r a -> (a -> a) -> StateT r m a
getAndModify T r a
f a -> a
g =
   do x <- T r a -> StateT r m a
forall (m :: * -> *) r a. Monad m => T r a -> StateT r m a
get T r a
f
      modify f g
      return x

{- |
Modify a record element and return its new value.
-}
modifyAndGet :: Monad m => Accessor.T r a -> (a -> a) -> StateT r m a
modifyAndGet :: forall (m :: * -> *) r a.
Monad m =>
T r a -> (a -> a) -> StateT r m a
modifyAndGet T r a
f a -> a
g =
   do T r a -> (a -> a) -> StateT r m ()
forall (m :: * -> *) r a.
Monad m =>
T r a -> (a -> a) -> StateT r m ()
modify T r a
f a -> a
g
      T r a -> StateT r m a
forall (m :: * -> *) r a. Monad m => T r a -> StateT r m a
get T r a
f



infix 1 %=, %:

{- |
Infix variant of 'set'.
-}
(%=) :: Monad m => Accessor.T r a -> a -> StateT r m ()
%= :: forall (m :: * -> *) r a. Monad m => T r a -> a -> StateT r m ()
(%=) = T r a -> a -> StateT r m ()
forall (m :: * -> *) r a. Monad m => T r a -> a -> StateT r m ()
set

{- |
Infix variant of 'modify'.
-}
(%:) :: Monad m => Accessor.T r a -> (a -> a) -> StateT r m ()
%: :: forall (m :: * -> *) r a.
Monad m =>
T r a -> (a -> a) -> StateT r m ()
(%:) = T r a -> (a -> a) -> StateT r m ()
forall (m :: * -> *) r a.
Monad m =>
T r a -> (a -> a) -> StateT r m ()
modify



-- * lift a state monadic accessor to an accessor of a parent record

lift :: Monad m => Accessor.T r s -> State s a -> StateT r m a
lift :: forall (m :: * -> *) r s a.
Monad m =>
T r s -> State s a -> StateT r m a
lift T r s
f State s a
m =
   do s0 <- T r s -> StateT r m s
forall (m :: * -> *) r a. Monad m => T r a -> StateT r m a
get T r s
f
      let (a,s1) = runState m s0
      set f s1
      return a

liftT :: (Monad m) =>
   Accessor.T r s -> StateT s m a -> StateT r m a
liftT :: forall (m :: * -> *) r s a.
Monad m =>
T r s -> StateT s m a -> StateT r m a
liftT T r s
f StateT s m a
m =
   do s0 <- T r s -> StateT r m s
forall (m :: * -> *) r a. Monad m => T r a -> StateT r m a
get T r s
f
      (a,s1) <- Trans.lift $ runStateT m s0
      set f s1
      return a