@@ -29,44 +29,66 @@ import Effectful.Monad
2929newtype State s :: Effect where
3030 State :: MVar s -> State s m r
3131
32+-- | Run a 'State' effect with the given initial state and return the final
33+-- value along with the final state.
3234runState :: s -> Eff (State s : es) a -> Eff es (a, s)
3335runState s m = do
3436 v <- unsafeEff_ $ newMVar s
3537 a <- evalEffect (IdE (State v)) m
3638 (a, ) <$> unsafeEff_ (readMVar v)
3739
40+-- | Run a 'State' effect with the given initial state and return the final
41+-- value, discarding the final state.
3842evalState :: s -> Eff (State s : es) a -> Eff es a
3943evalState s m = do
4044 v <- unsafeEff_ $ newMVar s
4145 evalEffect (IdE (State v)) m
4246
47+-- | Run a 'State' effect with the given initial state and return the final
48+-- state, discarding the final value.
4349execState :: s -> Eff (State s : es) a -> Eff es s
4450execState s m = do
4551 v <- unsafeEff_ $ newMVar s
4652 _ <- evalEffect (IdE (State v)) m
4753 unsafeEff_ $ readMVar v
4854
55+-- | Fetch the current value of the state.
4956get :: State s :> es => Eff es s
5057get = unsafeEff $ \es -> do
5158 IdE (State v) <- getEnv es
5259 readMVar v
5360
61+-- | Get a function of the current state.
62+--
63+-- @'gets' f ≡ f '<$>' 'get'@
5464gets :: State s :> es => (s -> a) -> Eff es a
5565gets f = f <$> get
5666
67+-- | Set the current state to the given value.
5768put :: State s :> es => s -> Eff es ()
5869put s = unsafeEff $ \es -> do
5970 IdE (State v) <- getEnv es
6071 modifyMVar_ v $ \_ -> s `seq` pure s
6172
73+-- | Apply the function to the current state and return a value.
74+--
75+-- /Note:/ this function gets an exclusive access to the state for its duration.
6276state :: State s :> es => (s -> (a, s)) -> Eff es a
6377state f = unsafeEff $ \es -> do
6478 IdE (State v) <- getEnv es
6579 modifyMVar v $ \s0 -> let (a, s) = f s0 in s `seq` pure (s, a)
6680
81+-- | Apply the function to the current state.
82+--
83+-- @'modify' f ≡ 'state' (\\s -> ((), f s))@
84+--
85+-- /Note:/ this function gets an exclusive access to the state for its duration.
6786modify :: State s :> es => (s -> s) -> Eff es ()
6887modify f = state (\s -> ((), f s))
6988
89+-- | Apply the monadic function to the current state and return a value.
90+--
91+-- /Note:/ this function gets an exclusive access to the state for its duration.
7092stateM :: State s :> es => (s -> Eff es (a, s)) -> Eff es a
7193stateM f = unsafeEff $ \es -> do
7294 IdE (State v) <- getEnv es
@@ -74,5 +96,10 @@ stateM f = unsafeEff $ \es -> do
7496 (a, s) <- unEff (f s0) es
7597 s `seq` pure (s, a)
7698
99+-- | Apply the monadic function to the current state.
100+--
101+-- @'modifyM' f ≡ 'stateM' (\\s -> ((), ) '<$>' f s)@
102+--
103+-- /Note:/ this function gets an exclusive access to the state for its duration.
77104modifyM :: State s :> es => (s -> Eff es s) -> Eff es ()
78105modifyM f = stateM (\s -> ((), ) <$> f s)