module MonadVar.Combinators
  ( postMutate_
  , preMutate_
  , postMutate
  , preMutate
  , postMutateM_
  , preMutateM_
  , postMutateM
  , preMutateM
  ) where
  
import           MonadVar.Prelude
import           MonadVar.Classes

-- | Mutate a variable and also return its old value.
postMutate_
  :: MonadMutate m v => v a -> (a -> a) -> m a
postMutate_ :: v a -> (a -> a) -> m a
postMutate_ v a
v a -> a
f = v a -> (a -> (a, a)) -> m a
forall (m :: * -> *) (v :: * -> *) a b.
MonadMutate m v =>
v a -> (a -> (a, b)) -> m b
mutate v a
v ((a -> (a, a)) -> m a) -> (a -> (a, a)) -> m a
forall a b. (a -> b) -> a -> b
$ \a
x -> a -> a
f a
x a -> (a -> (a, a)) -> (a, a)
forall a b. a -> (a -> b) -> b
& \a
y -> (a
y, a
x)
{-# INLINE postMutate_ #-}

-- | Mutate a variable and also return its new value.
preMutate_
  :: MonadMutate m v => v a -> (a -> a) -> m a
preMutate_ :: v a -> (a -> a) -> m a
preMutate_ v a
v a -> a
f = v a -> (a -> (a, a)) -> m a
forall (m :: * -> *) (v :: * -> *) a b.
MonadMutate m v =>
v a -> (a -> (a, b)) -> m b
mutate v a
v ((a -> (a, a)) -> m a) -> (a -> (a, a)) -> m a
forall a b. (a -> b) -> a -> b
$ \a
x -> a -> a
f a
x a -> (a -> (a, a)) -> (a, a)
forall a b. a -> (a -> b) -> b
& \a
y -> (a
y, a
y)
{-# INLINE preMutate_ #-}

-- | Mutate a variable and also return its old value
-- along with an additional value.
postMutate
  :: MonadMutate m v => v a -> (a -> (a, b)) -> m (a, b)
postMutate :: v a -> (a -> (a, b)) -> m (a, b)
postMutate v a
v a -> (a, b)
f = v a -> (a -> (a, (a, b))) -> m (a, b)
forall (m :: * -> *) (v :: * -> *) a b.
MonadMutate m v =>
v a -> (a -> (a, b)) -> m b
mutate v a
v ((a -> (a, (a, b))) -> m (a, b)) -> (a -> (a, (a, b))) -> m (a, b)
forall a b. (a -> b) -> a -> b
$ \a
x -> a -> (a, b)
f a
x (a, b) -> ((a, b) -> (a, (a, b))) -> (a, (a, b))
forall a b. a -> (a -> b) -> b
& \(a
y, b
z) -> (a
y, (a
x, b
z))
{-# INLINE postMutate #-}

-- | Mutate a variable and also return its new value
-- along with an additional value.
preMutate
  :: MonadMutate m v => v a -> (a -> (a, b)) -> m (a, b)
preMutate :: v a -> (a -> (a, b)) -> m (a, b)
preMutate v a
v a -> (a, b)
f = v a -> (a -> (a, (a, b))) -> m (a, b)
forall (m :: * -> *) (v :: * -> *) a b.
MonadMutate m v =>
v a -> (a -> (a, b)) -> m b
mutate v a
v ((a -> (a, (a, b))) -> m (a, b)) -> (a -> (a, (a, b))) -> m (a, b)
forall a b. (a -> b) -> a -> b
$ \a
x -> a -> (a, b)
f a
x (a, b) -> ((a, b) -> (a, (a, b))) -> (a, (a, b))
forall a b. a -> (a -> b) -> b
& \(a
y, b
z) -> (a
y, (a
y, b
z))
{-# INLINE preMutate #-}

-- | Monadically mutate a variable and also return its old value.
postMutateM_
  :: (MonadMutateM f m v, Functor f) => v a -> (a -> f a) -> m a
postMutateM_ :: v a -> (a -> f a) -> m a
postMutateM_ v a
v a -> f a
f = v a -> (a -> f (a, a)) -> m a
forall (f :: * -> *) (m :: * -> *) (v :: * -> *) a b.
MonadMutateM f m v =>
v a -> (a -> f (a, b)) -> m b
mutateM v a
v ((a -> f (a, a)) -> m a) -> (a -> f (a, a)) -> m a
forall a b. (a -> b) -> a -> b
$ \a
x -> a -> f a
f a
x f a -> (a -> (a, a)) -> f (a, a)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \a
y -> (a
y, a
x)
{-# INLINE postMutateM_ #-}

-- | Monadically mutate a variable and also return its new value.
preMutateM_
  :: (MonadMutateM f m v, Functor f) => v a -> (a -> f a) -> m a
preMutateM_ :: v a -> (a -> f a) -> m a
preMutateM_ v a
v a -> f a
f = v a -> (a -> f (a, a)) -> m a
forall (f :: * -> *) (m :: * -> *) (v :: * -> *) a b.
MonadMutateM f m v =>
v a -> (a -> f (a, b)) -> m b
mutateM v a
v ((a -> f (a, a)) -> m a) -> (a -> f (a, a)) -> m a
forall a b. (a -> b) -> a -> b
$ \a
x -> a -> f a
f a
x f a -> (a -> (a, a)) -> f (a, a)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \a
y -> (a
y, a
y)
{-# INLINE preMutateM_ #-}

-- | Monadically mutate a variable and also return its old value
-- along with an additional value.
postMutateM
  :: (MonadMutateM f m v, Functor f) => v a -> (a -> f (a, b)) -> m (a, b)
postMutateM :: v a -> (a -> f (a, b)) -> m (a, b)
postMutateM v a
v a -> f (a, b)
f = v a -> (a -> f (a, (a, b))) -> m (a, b)
forall (f :: * -> *) (m :: * -> *) (v :: * -> *) a b.
MonadMutateM f m v =>
v a -> (a -> f (a, b)) -> m b
mutateM v a
v ((a -> f (a, (a, b))) -> m (a, b))
-> (a -> f (a, (a, b))) -> m (a, b)
forall a b. (a -> b) -> a -> b
$ \a
x -> a -> f (a, b)
f a
x f (a, b) -> ((a, b) -> (a, (a, b))) -> f (a, (a, b))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \(a
y, b
z) -> (a
y, (a
x, b
z))
{-# INLINE postMutateM #-}

-- | Monadically mutate a variable and also return its new value
-- along with an additional value.
preMutateM
  :: (MonadMutateM f m v, Functor f) => v a -> (a -> f (a, b)) -> m (a, b)
preMutateM :: v a -> (a -> f (a, b)) -> m (a, b)
preMutateM v a
v a -> f (a, b)
f = v a -> (a -> f (a, (a, b))) -> m (a, b)
forall (f :: * -> *) (m :: * -> *) (v :: * -> *) a b.
MonadMutateM f m v =>
v a -> (a -> f (a, b)) -> m b
mutateM v a
v ((a -> f (a, (a, b))) -> m (a, b))
-> (a -> f (a, (a, b))) -> m (a, b)
forall a b. (a -> b) -> a -> b
$ \a
x -> a -> f (a, b)
f a
x f (a, b) -> ((a, b) -> (a, (a, b))) -> f (a, (a, b))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \(a
y, b
z) -> (a
y, (a
y, b
z))
{-# INLINE preMutateM #-}