{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Control.Carrier.State.Lazy
(
runState
, evalState
, execState
, StateC(..)
, module Control.Effect.State
) where
import Control.Algebra
import Control.Applicative (Alternative(..))
import Control.Effect.State
import Control.Monad (MonadPlus)
import Control.Monad.Fail as Fail
import Control.Monad.Fix
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
runState :: s -> StateC s m a -> m (s, a)
runState :: forall s (m :: * -> *) a. s -> StateC s m a -> m (s, a)
runState s
s (StateC s -> m (s, a)
runStateC) = s -> m (s, a)
runStateC s
s
{-# INLINE[3] runState #-}
evalState :: forall s m a . Functor m => s -> StateC s m a -> m a
evalState :: forall s (m :: * -> *) a. Functor m => s -> StateC s m a -> m a
evalState s
s = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. s -> StateC s m a -> m (s, a)
runState s
s
{-# INLINE[3] evalState #-}
execState :: forall s m a . Functor m => s -> StateC s m a -> m s
execState :: forall s (m :: * -> *) a. Functor m => s -> StateC s m a -> m s
execState s
s = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. s -> StateC s m a -> m (s, a)
runState s
s
{-# INLINE[3] execState #-}
newtype StateC s m a = StateC (s -> m (s, a))
instance Functor m => Functor (StateC s m) where
fmap :: forall a b. (a -> b) -> StateC s m a -> StateC s m b
fmap a -> b
f StateC s m a
m = forall s (m :: * -> *) a. (s -> m (s, a)) -> StateC s m a
StateC forall a b. (a -> b) -> a -> b
$ \ s
s -> (\ ~(s
s', a
a) -> (s
s', a -> b
f a
a)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) a. s -> StateC s m a -> m (s, a)
runState s
s StateC s m a
m
{-# INLINE fmap #-}
instance Monad m => Applicative (StateC s m) where
pure :: forall a. a -> StateC s m a
pure a
a = forall s (m :: * -> *) a. (s -> m (s, a)) -> StateC s m a
StateC forall a b. (a -> b) -> a -> b
$ \ s
s -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (s
s, a
a)
{-# INLINE pure #-}
StateC s -> m (s, a -> b)
mf <*> :: forall a b. StateC s m (a -> b) -> StateC s m a -> StateC s m b
<*> StateC s -> m (s, a)
mx = forall s (m :: * -> *) a. (s -> m (s, a)) -> StateC s m a
StateC forall a b. (a -> b) -> a -> b
$ \ s
s -> do
~(s
s', a -> b
f) <- s -> m (s, a -> b)
mf s
s
~(s
s'', a
x) <- s -> m (s, a)
mx s
s'
forall (f :: * -> *) a. Applicative f => a -> f a
pure (s
s'', a -> b
f a
x)
{-# INLINE (<*>) #-}
StateC s m a
m *> :: forall a b. StateC s m a -> StateC s m b -> StateC s m b
*> StateC s m b
k = StateC s m a
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a b. a -> b -> a
const StateC s m b
k
{-# INLINE (*>) #-}
instance Monad m => Monad (StateC s m) where
StateC s m a
m >>= :: forall a b. StateC s m a -> (a -> StateC s m b) -> StateC s m b
>>= a -> StateC s m b
k = forall s (m :: * -> *) a. (s -> m (s, a)) -> StateC s m a
StateC forall a b. (a -> b) -> a -> b
$ \ s
s -> do
~(s
s', a
a) <- forall s (m :: * -> *) a. s -> StateC s m a -> m (s, a)
runState s
s StateC s m a
m
forall s (m :: * -> *) a. s -> StateC s m a -> m (s, a)
runState s
s' (a -> StateC s m b
k a
a)
{-# INLINE (>>=) #-}
instance (Alternative m, Monad m) => Alternative (StateC s m) where
empty :: forall a. StateC s m a
empty = forall s (m :: * -> *) a. (s -> m (s, a)) -> StateC s m a
StateC (forall a b. a -> b -> a
const forall (f :: * -> *) a. Alternative f => f a
empty)
{-# INLINE empty #-}
StateC s -> m (s, a)
l <|> :: forall a. StateC s m a -> StateC s m a -> StateC s m a
<|> StateC s -> m (s, a)
r = forall s (m :: * -> *) a. (s -> m (s, a)) -> StateC s m a
StateC (\ s
s -> s -> m (s, a)
l s
s forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> s -> m (s, a)
r s
s)
{-# INLINE (<|>) #-}
instance Fail.MonadFail m => Fail.MonadFail (StateC s m) where
fail :: forall a. String -> StateC s m a
fail String
s = forall s (m :: * -> *) a. (s -> m (s, a)) -> StateC s m a
StateC (forall a b. a -> b -> a
const (forall (m :: * -> *) a. MonadFail m => String -> m a
Fail.fail String
s))
{-# INLINE fail #-}
instance MonadFix m => MonadFix (StateC s m) where
mfix :: forall a. (a -> StateC s m a) -> StateC s m a
mfix a -> StateC s m a
f = forall s (m :: * -> *) a. (s -> m (s, a)) -> StateC s m a
StateC (\ s
s -> forall (m :: * -> *) a. MonadFix m => (a -> m a) -> m a
mfix (forall s (m :: * -> *) a. s -> StateC s m a -> m (s, a)
runState s
s forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> StateC s m a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd))
{-# INLINE mfix #-}
instance MonadIO m => MonadIO (StateC s m) where
liftIO :: forall a. IO a -> StateC s m a
liftIO IO a
io = forall s (m :: * -> *) a. (s -> m (s, a)) -> StateC s m a
StateC (\ s
s -> (,) s
s forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO a
io)
{-# INLINE liftIO #-}
instance (Alternative m, Monad m) => MonadPlus (StateC s m)
instance MonadTrans (StateC s) where
lift :: forall (m :: * -> *) a. Monad m => m a -> StateC s m a
lift m a
m = forall s (m :: * -> *) a. (s -> m (s, a)) -> StateC s m a
StateC (\ s
s -> (,) s
s forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
m)
{-# INLINE lift #-}
instance Algebra sig m => Algebra (State s :+: sig) (StateC s m) where
alg :: forall (ctx :: * -> *) (n :: * -> *) a.
Functor ctx =>
Handler ctx n (StateC s m)
-> (:+:) (State s) sig n a -> ctx () -> StateC s m (ctx a)
alg Handler ctx n (StateC s m)
hdl (:+:) (State s) sig n a
sig ctx ()
ctx = forall s (m :: * -> *) a. (s -> m (s, a)) -> StateC s m a
StateC forall a b. (a -> b) -> a -> b
$ \ s
s -> case (:+:) (State s) sig n a
sig of
L State s n a
Get -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (s
s, s
s forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ctx ()
ctx)
L (Put s
s) -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (s
s, ctx ()
ctx)
R sig n a
other -> forall (ctx1 :: * -> *) (ctx2 :: * -> *)
(sig :: (* -> *) -> * -> *) (m :: * -> *) (n :: * -> *) a.
(Functor ctx1, Functor ctx2, Algebra sig m) =>
Handler (Compose ctx1 ctx2) n m
-> sig n a -> ctx1 (ctx2 ()) -> m (ctx1 (ctx2 a))
thread (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall s (m :: * -> *) a. s -> StateC s m a -> m (s, a)
runState forall (n :: * -> *) (ctx1 :: * -> *) (m :: * -> *)
(ctx2 :: * -> *) (l :: * -> *).
(Functor n, Functor ctx1) =>
Handler ctx1 m n
-> Handler ctx2 l m -> Handler (Compose ctx1 ctx2) l n
~<~ Handler ctx n (StateC s m)
hdl) sig n a
other (s
s, ctx ()
ctx)
{-# INLINE alg #-}