{-# LANGUAGE DeriveFunctor, ExplicitForAll, FlexibleContexts, FlexibleInstances, KindSignatures, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
module Control.Effect.State.Internal
( State(..)
, get
, gets
, put
, modify
, modifyLazy
) where
import Control.Effect.Carrier
import Control.Effect.Sum
import Data.Coerce
import Prelude hiding (fail)
data State s (m :: * -> *) k
= Get (s -> k)
| Put s k
deriving (Functor)
instance HFunctor (State s) where
hmap _ = coerce
{-# INLINE hmap #-}
instance Effect (State s) where
handle state handler (Get k) = Get (handler . (<$ state) . k)
handle state handler (Put s k) = Put s (handler . (<$ state) $ k)
get :: (Member (State s) sig, Carrier sig m) => m s
get = send (Get pure)
gets :: (Member (State s) sig, Carrier sig m) => (s -> a) -> m a
gets f = send (Get (pure . f))
put :: (Member (State s) sig, Carrier sig m) => s -> m ()
put s = send (Put s (pure ()))
modify :: (Member (State s) sig, Carrier sig m) => (s -> s) -> m ()
modify f = do
a <- get
put $! f a
modifyLazy :: (Member (State s) sig, Carrier sig m) => (s -> s) -> m ()
modifyLazy f = get >>= put . f