----------------------------------------------------------------------------- -- | -- Module : Control.Effect.State.Lazy -- Copyright : (c) Michael Szvetits, 2020 -- License : BSD3 (see the file LICENSE) -- Maintainer : typedbyte@qualified.name -- Stability : stable -- Portability : portable -- -- Lazy interpretations of the 'State'' effect. -- -- If you don't require disambiguation of multiple state effects -- (i.e., you only have one state effect in your monadic context), -- you usually need the untagged interpretations. ----------------------------------------------------------------------------- module Control.Effect.State.Lazy ( -- * Tagged Interpretations evalState' , execState' , runState' -- * Untagged Interpretations , evalState , execState , runState ) where -- base import Data.Tuple (swap) -- transformers import Control.Monad.Trans.State.Lazy (StateT, runStateT) import Control.Effect.State (State, State') import Control.Effect.Machinery (G, Via, runVia) -- | Runs the state effect and discards the final state. evalState' :: forall tag s m a. Functor m => s -- ^ The initial state. -> (State' tag s `Via` StateT s) m a -- ^ The program whose state effect should be handled. -> m a -- ^ The program with its state effect handled. evalState' s = fmap fst . flip runStateT s . runVia {-# INLINE evalState' #-} -- | The untagged version of 'evalState''. evalState :: Functor m => s -> (State s `Via` StateT s) m a -> m a evalState = evalState' @G {-# INLINE evalState #-} -- | Runs the state effect and discards the result of the interpreted program. execState' :: forall tag s m a. Functor m => s -- ^ The initial state. -> (State' tag s `Via` StateT s) m a -- ^ The program whose state effect should be handled. -> m s -- ^ The program with its state effect handled, producing the final state @s@. execState' s = fmap snd . flip runStateT s . runVia {-# INLINE execState' #-} -- | The untagged version of 'execState''. execState :: Functor m => s -> (State s `Via` StateT s) m a -> m s execState = execState' @G {-# INLINE execState #-} -- | Runs the state effect and returns both the final state and the result of the interpreted program. runState' :: forall tag s m a. Functor m => s -- ^ The initial state. -> (State' tag s `Via` StateT s) m a -- ^ The program whose state effect should be handled. -> m (s, a) -- ^ The program with its state effect handled, producing the final state @s@ and the result @a@. runState' s = fmap swap . flip runStateT s . runVia {-# INLINE runState' #-} -- | The untagged version of 'runState''. runState :: Functor m => s -> (State s `Via` StateT s) m a -> m (s, a) runState = runState' @G {-# INLINE runState #-}