joint-0.1.4: Control/Joint/Effects/State.hs
module Control.Joint.Effects.State where
import Control.Joint.Core (type (:.), type (:=))
import Control.Joint.Abilities.Composition (Composition (Primary, run))
import Control.Joint.Abilities.Transformer (Transformer (Schema, embed, build, unite))
import Control.Joint.Abilities.Liftable (Liftable (lift))
import Control.Joint.Schemes.TU (TU (TU))
import Control.Joint.Schemes.TUT (TUT (TUT))
import Control.Joint.Schemes.UT (UT (UT))
import Control.Joint.Effects.Reader (Reader (Reader))
newtype State s a = State ((->) s :. (,) s := a)
statefully :: s -> State s a -> (s, a)
statefully initial (State x) = x initial
instance Functor (State s) where
fmap f (State x) = State $ \old -> f <$> x old
instance Applicative (State s) where
pure x = State $ \s -> (s, x)
State f <*> State x = State $ \old ->
let latest = fst . x $ old in
(latest, snd (f old) . snd . x $ old)
instance Monad (State s) where
State x >>= f = State $ \old ->
uncurry statefully $ f <$> x old
instance Composition (State s) where
type Primary (State s) a = (->) s :. (,) s := a
run (State x) = x
instance Transformer (State s) where
type Schema (State s) u = TUT ((->) s) u ((,) s)
embed x = TUT $ \s -> (s,) <$> x
build x = TUT $ pure <$> run x
unite = TUT
instance Functor u => Functor (TUT ((->) s) u ((,) s)) where
fmap f (TUT x) = TUT $ \old -> (fmap . fmap) f $ x old
instance Monad u => Applicative (TUT ((->) s) u ((,) s)) where
pure x = TUT $ \s -> pure (s, x)
TUT f <*> TUT x = TUT $ \old -> f old >>= \(new, g) -> (fmap . fmap) g $ x new
instance Monad u => Monad (TUT ((->) s) u ((,) s)) where
TUT x >>= f = TUT $ \old -> x old >>= \(new, y) -> ($ new) . run . f $ y
get :: State s s
get = State $ \s -> (s, s)
modify :: (s -> s) -> State s ()
modify f = State $ \s -> (f s, ())
put :: s -> State s ()
put s = State $ \_ -> (s, ())
instance Liftable (Reader e) (State e) where
lift (Reader f) = State (\e -> (e, f e))
type Stateful e = Liftable (State e)