on b8fb0bd help sign in
121 lines 3.0 kB history raw
1-- | The 'State' as an effect with dynamic dispatch.
2--
3-- It's not clear in which situation it's beneficial to use this instead of
4-- "Effectful.State" or "Effectful.State.MVar" as you either:
5--
6-- - Share state between threads and need the synchonized version.
7--
8-- - Don't share state between threads (or need them to be thread local) and are
9-- free to use the faster, pure version.
10--
11-- However, let's include this for now.
12--
13module Effectful.State.Dynamic
14 ( State(..)
16 -- * Pure
17 , runState
18 , evalState
19 , execState
21 -- * MVar
22 , runStateMVar
23 , evalStateMVar
24 , execStateMVar
26 -- * Operations
27 , get
28 , gets
29 , put
30 , state
31 , modify
32 , stateM
33 , modifyM
34 ) where
36import Effectful.Internal.Effect
37import Effectful.Internal.Monad
38import Effectful.Interpreter
40import qualified Effectful.State as SP
41import qualified Effectful.State.MVar as SM
43-- | Provide access to a mutable state of type @s@.
44--
45-- Whether the state is represented as a pure value or an 'MVar' underneath
46-- depends on the interpretation.
47data State s :: Effect where
48 Get :: State s m s
49 Put :: ~s -> State s m ()
50 State :: (s -> (a, s)) -> State s m a
51 StateM :: (s -> m (a, s)) -> State s m a
53----------------------------------------
54-- Pure
56runState :: s -> Eff (State s : es) a -> Eff es (a, s)
57runState s0 = reinterpretM (SP.runState s0) statePure
59evalState :: s -> Eff (State s : es) a -> Eff es a
60evalState s0 = reinterpretM (SP.evalState s0) statePure
62execState :: s -> Eff (State s : es) a -> Eff es s
63execState s0 = reinterpretM (SP.execState s0) statePure
65statePure
66 :: SP.State s :> es
67 => (forall r. Eff es0 r -> Eff es r)
68 -> State s (Eff es0) a
69 -> Eff es a
70statePure run = \case
71 Get -> SP.get
72 Put s -> SP.put s
73 State f -> SP.state f
74 StateM f -> SP.stateM (run . f)
76----------------------------------------
77-- MVar
79runStateMVar :: s -> Eff (State s : es) a -> Eff es (a, s)
80runStateMVar s0 = reinterpretM (SM.runState s0) stateMVar
82evalStateMVar :: s -> Eff (State s : es) a -> Eff es a
83evalStateMVar s0 = reinterpretM (SM.evalState s0) stateMVar
85execStateMVar :: s -> Eff (State s : es) a -> Eff es s
86execStateMVar s0 = reinterpretM (SM.execState s0) stateMVar
88stateMVar
89 :: SM.State s :> es
90 => (forall r. Eff es0 r -> Eff es r)
91 -> State s (Eff es0) a
92 -> Eff es a
93stateMVar run = \case
94 Get -> SM.get
95 Put s -> SM.put s
96 State f -> SM.state f
97 StateM f -> SM.stateM (run . f)
99----------------------------------------
100-- Operations
102get :: State s :> es => Eff es s
103get = send Get
105gets :: State s :> es => (s -> a) -> Eff es a
106gets f = f <$> get
108put :: State s :> es => s -> Eff es ()
109put = send . Put
111state :: (State s :> es) => (s -> (a, s)) -> Eff es a
112state = send . State
114modify :: State s :> es => (s -> s) -> Eff es ()
115modify f = state (\s -> ((), f s))
117stateM :: State s :> es => (s -> Eff es (a, s)) -> Eff es a
118stateM = send . StateM
120modifyM :: State s :> es => (s -> Eff es s) -> Eff es ()
121modifyM f = stateM (\s -> ((), ) <$> f s)