{- |
Module      :  Control.Monad.Trans.Indexed.State
Copyright   :  (C) 2024 Eitan Chatav
License     :  BSD 3-Clause License (see the file LICENSE)
Maintainer  :  Eitan Chatav <eitan.chatav@gmail.com>

The state indexed monad transformer.
-}

module Control.Monad.Trans.Indexed.State
  ( StateIx (..)
  , evalStateIx
  , execStateIx
  , modifyIx
  , putIx
  , toStateT
  , fromStateT
  ) where

import Control.Monad.State
import Control.Monad.Trans.Indexed

newtype StateIx i j m x = StateIx { forall i j (m :: * -> *) x. StateIx i j m x -> i -> m (x, j)
runStateIx :: i -> m (x, j)}
  deriving (forall a b. (a -> b) -> StateIx i j m a -> StateIx i j m b)
-> (forall a b. a -> StateIx i j m b -> StateIx i j m a)
-> Functor (StateIx i j m)
forall a b. a -> StateIx i j m b -> StateIx i j m a
forall a b. (a -> b) -> StateIx i j m a -> StateIx i j m b
forall i j (m :: * -> *) a b.
Functor m =>
a -> StateIx i j m b -> StateIx i j m a
forall i j (m :: * -> *) a b.
Functor m =>
(a -> b) -> StateIx i j m a -> StateIx i j m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall i j (m :: * -> *) a b.
Functor m =>
(a -> b) -> StateIx i j m a -> StateIx i j m b
fmap :: forall a b. (a -> b) -> StateIx i j m a -> StateIx i j m b
$c<$ :: forall i j (m :: * -> *) a b.
Functor m =>
a -> StateIx i j m b -> StateIx i j m a
<$ :: forall a b. a -> StateIx i j m b -> StateIx i j m a
Functor
instance IxMonadTrans StateIx where
  joinIx :: forall (m :: * -> *) i j k1 y.
Monad m =>
StateIx i j m (StateIx j k1 m y) -> StateIx i k1 m y
joinIx (StateIx i -> m (StateIx j k1 m y, j)
f) = (i -> m (y, k1)) -> StateIx i k1 m y
forall i j (m :: * -> *) x. (i -> m (x, j)) -> StateIx i j m x
StateIx ((i -> m (y, k1)) -> StateIx i k1 m y)
-> (i -> m (y, k1)) -> StateIx i k1 m y
forall a b. (a -> b) -> a -> b
$ \i
i -> do
    (StateIx j -> m (y, k1)
g, j
j) <- i -> m (StateIx j k1 m y, j)
f i
i
    j -> m (y, k1)
g j
j
instance (i ~ j, Monad m) => Applicative (StateIx i j m) where
  pure :: forall a. a -> StateIx i j m a
pure a
x = (i -> m (a, j)) -> StateIx i j m a
forall i j (m :: * -> *) x. (i -> m (x, j)) -> StateIx i j m x
StateIx ((i -> m (a, j)) -> StateIx i j m a)
-> (i -> m (a, j)) -> StateIx i j m a
forall a b. (a -> b) -> a -> b
$ \i
i -> (a, j) -> m (a, j)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
x, i
j
i)
  <*> :: forall a b.
StateIx i j m (a -> b) -> StateIx i j m a -> StateIx i j m b
(<*>) = StateIx i j m (a -> b) -> StateIx i j m a -> StateIx i j m b
StateIx i j m (a -> b) -> StateIx j j m a -> StateIx i j m b
forall k (t :: k -> k -> (* -> *) -> * -> *) (m :: * -> *) (i :: k)
       (j :: k) x y (k1 :: k).
(IxMonadTrans t, Monad m) =>
t i j m (x -> y) -> t j k1 m x -> t i k1 m y
forall (m :: * -> *) i j x y k1.
Monad m =>
StateIx i j m (x -> y) -> StateIx j k1 m x -> StateIx i k1 m y
apIx
instance (i ~ j, Monad m) => Monad (StateIx i j m) where
  return :: forall a. a -> StateIx i j m a
return = a -> StateIx i j m a
forall a. a -> StateIx i j m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  >>= :: forall a b.
StateIx i j m a -> (a -> StateIx i j m b) -> StateIx i j m b
(>>=) = ((a -> StateIx i j m b) -> StateIx i j m a -> StateIx i j m b)
-> StateIx i j m a -> (a -> StateIx i j m b) -> StateIx i j m b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> StateIx i j m b) -> StateIx i i m a -> StateIx i j m b
(a -> StateIx i j m b) -> StateIx i j m a -> StateIx i j m b
forall k (t :: k -> k -> (* -> *) -> * -> *) (m :: * -> *) x
       (j :: k) (k1 :: k) y (i :: k).
(IxMonadTrans t, Monad m) =>
(x -> t j k1 m y) -> t i j m x -> t i k1 m y
forall (m :: * -> *) x j k1 y i.
Monad m =>
(x -> StateIx j k1 m y) -> StateIx i j m x -> StateIx i k1 m y
bindIx
instance i ~ j => MonadTrans (StateIx i j) where
  lift :: forall (m :: * -> *) a. Monad m => m a -> StateIx i j m a
lift m a
m = (i -> m (a, j)) -> StateIx i j m a
forall i j (m :: * -> *) x. (i -> m (x, j)) -> StateIx i j m x
StateIx ((i -> m (a, j)) -> StateIx i j m a)
-> (i -> m (a, j)) -> StateIx i j m a
forall a b. (a -> b) -> a -> b
$ \i
i -> (, i
i) (a -> (a, j)) -> m a -> m (a, j)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
m
instance (i ~ j, Monad m) => MonadState i (StateIx i j m) where
  state :: forall a. (i -> (a, i)) -> StateIx i j m a
state i -> (a, i)
f = (i -> m (a, j)) -> StateIx i j m a
forall i j (m :: * -> *) x. (i -> m (x, j)) -> StateIx i j m x
StateIx ((a, j) -> m (a, j)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ((a, j) -> m (a, j)) -> (i -> (a, j)) -> i -> m (a, j)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> (a, i)
i -> (a, j)
f)

evalStateIx :: Monad m => StateIx i j m x -> i -> m x
evalStateIx :: forall (m :: * -> *) i j x. Monad m => StateIx i j m x -> i -> m x
evalStateIx StateIx i j m x
m i
i = (x, j) -> x
forall a b. (a, b) -> a
fst ((x, j) -> x) -> m (x, j) -> m x
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateIx i j m x -> i -> m (x, j)
forall i j (m :: * -> *) x. StateIx i j m x -> i -> m (x, j)
runStateIx StateIx i j m x
m i
i

execStateIx :: Monad m => StateIx i j m x -> i -> m j
execStateIx :: forall (m :: * -> *) i j x. Monad m => StateIx i j m x -> i -> m j
execStateIx StateIx i j m x
m i
i = (x, j) -> j
forall a b. (a, b) -> b
snd ((x, j) -> j) -> m (x, j) -> m j
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateIx i j m x -> i -> m (x, j)
forall i j (m :: * -> *) x. StateIx i j m x -> i -> m (x, j)
runStateIx StateIx i j m x
m i
i

modifyIx :: Applicative m => (i -> j) -> StateIx i j m ()
modifyIx :: forall (m :: * -> *) i j.
Applicative m =>
(i -> j) -> StateIx i j m ()
modifyIx i -> j
f = (i -> m ((), j)) -> StateIx i j m ()
forall i j (m :: * -> *) x. (i -> m (x, j)) -> StateIx i j m x
StateIx ((i -> m ((), j)) -> StateIx i j m ())
-> (i -> m ((), j)) -> StateIx i j m ()
forall a b. (a -> b) -> a -> b
$ \i
i -> ((), j) -> m ((), j)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((), i -> j
f i
i)

putIx :: Applicative m => j -> StateIx i j m ()
putIx :: forall (m :: * -> *) j i. Applicative m => j -> StateIx i j m ()
putIx j
j = (i -> j) -> StateIx i j m ()
forall (m :: * -> *) i j.
Applicative m =>
(i -> j) -> StateIx i j m ()
modifyIx (\ i
_ -> j
j)

toStateT :: StateIx i i m x -> StateT i m x
toStateT :: forall i (m :: * -> *) x. StateIx i i m x -> StateT i m x
toStateT (StateIx i -> m (x, i)
f) = (i -> m (x, i)) -> StateT i m x
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateT i -> m (x, i)
f

fromStateT :: StateT i m x -> StateIx i i m x
fromStateT :: forall i (m :: * -> *) x. StateT i m x -> StateIx i i m x
fromStateT (StateT i -> m (x, i)
f) = (i -> m (x, i)) -> StateIx i i m x
forall i j (m :: * -> *) x. (i -> m (x, j)) -> StateIx i j m x
StateIx i -> m (x, i)
f