on 043bffe help sign in
119 lines 3.0 kB history raw
1-- | The 'State' 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 want it 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.Interpreter
37import Effectful.Monad
38import qualified Effectful.State as SP
39import qualified Effectful.State.MVar as SM
41-- | Provide access to a mutable state of type @s@.
42--
43-- Whether the state is represented as a pure value or an 'MVar' underneath
44-- depends on the interpretation.
45data State s :: Effect where
46 Get :: State s m s
47 Put :: ~s -> State s m ()
48 State :: (s -> (a, s)) -> State s m a
49 StateM :: (s -> m (a, s)) -> State s m a
51----------------------------------------
52-- Pure
54runState :: s -> Eff (State s : es) a -> Eff es (a, s)
55runState s0 = reinterpretM (SP.runState s0) statePure
57evalState :: s -> Eff (State s : es) a -> Eff es a
58evalState s0 = reinterpretM (SP.evalState s0) statePure
60execState :: s -> Eff (State s : es) a -> Eff es s
61execState s0 = reinterpretM (SP.execState s0) statePure
63statePure
64 :: SP.State s :> es
65 => LocalEnv localEs
66 -> State s (Eff localEs) a
67 -> Eff es a
68statePure env = \case
69 Get -> SP.get
70 Put s -> SP.put s
71 State f -> SP.state f
72 StateM f -> localSeqUnlift env $ \run -> SP.stateM (run . f)
74----------------------------------------
75-- MVar
77runStateMVar :: s -> Eff (State s : es) a -> Eff es (a, s)
78runStateMVar s0 = reinterpretM (SM.runState s0) stateMVar
80evalStateMVar :: s -> Eff (State s : es) a -> Eff es a
81evalStateMVar s0 = reinterpretM (SM.evalState s0) stateMVar
83execStateMVar :: s -> Eff (State s : es) a -> Eff es s
84execStateMVar s0 = reinterpretM (SM.execState s0) stateMVar
86stateMVar
87 :: SM.State s :> es
88 => LocalEnv localEs
89 -> State s (Eff localEs) a
90 -> Eff es a
91stateMVar env = \case
92 Get -> SM.get
93 Put s -> SM.put s
94 State f -> SM.state f
95 StateM f -> localSeqUnlift env $ \run -> SM.stateM (run . f)
97----------------------------------------
98-- Operations
100get :: State s :> es => Eff es s
101get = send Get
103gets :: State s :> es => (s -> a) -> Eff es a
104gets f = f <$> get
106put :: State s :> es => s -> Eff es ()
107put = send . Put
109state :: (State s :> es) => (s -> (a, s)) -> Eff es a
110state = send . State
112modify :: State s :> es => (s -> s) -> Eff es ()
113modify f = state (\s -> ((), f s))
115stateM :: State s :> es => (s -> Eff es (a, s)) -> Eff es a
116stateM = send . StateM
118modifyM :: State s :> es => (s -> Eff es s) -> Eff es ()
119modifyM f = stateM (\s -> ((), ) <$> f s)