-- (c) MP-I and CP (1998/99-2022/23) module St where import Cp import Control.Applicative ------------------------------------------------------------------ -- NB: This is a small, pointfree "summary" of Control.Monad.State ------------------------------------------------------------------ data St s a = St { st :: (s -> (a, s)) } inSt = St outSt = st -- NB: "values" of this monad are actions rather than states. -- So this should be called the "action monad" and not the -- "state monad". -- (Unfortunately, it is to late to change terminology.) -------------------------------------------------------------------------- instance Monad (St s) where return = St . (curry id) (St x) >>= g = St (uncurry(st . g) . x ) {-- ie: (St x) >>= g = St (\s -> let (a,s') = x s St k = g a in k s') --} -------------------------------------------------------------------------- instance Functor (St s) where fmap f t = do { a <- t ; return (f a) } -- as in every monad -- ie: fmap f (St g) = St(\s -> let (a,s') = g s in (f a,s')) -------------------------------------------------------------------------- -- action execution exec :: St s a -> s -> (a, s) exec (St g) s = g s -- splits evalState and execState -- generic actions get :: St s s -- as in class MonadState get = St(split id id) modify :: (s -> s) -> St s () modify f = St(split (!) f) put :: s -> St s () -- as in class MonadState put s = modify (const s) query :: (s -> a) -> St s a query f = St(split f id) trans :: (s -> s) -> (s -> a) -> St s a -- a simple transation trans g f = do { modify g ; query f } -- actions with input meth :: ((a, s) -> (b, s)) -> a -> St s b meth f = St.(curry f) -- create "method" from function -- update state, then query updfst :: (a -> s -> s) -> (a -> s -> b) -> a -> St s b updfst g f a = St (split (f a) id . (g a)) -- updfst g f a = do { modify (g a) ; query (f a)} -- example (ATM credit) credit = updfst (+) (bal) where bal a s = "credited= "++show a ++ ", bal= "++ show s -- query state, then update qryfst :: (a -> s -> s) -> (a -> s -> b) -> a -> St s b qryfst g f a = St(split (f a) (g a)) -- qryfst g f a = do { b <- query (f a); modify (g a) ; return b } -- example (pop) pop_action = qryfst (\_ -> tail) (\_ -> head) -- execute forever loop :: Monad m => m a -> m b loop x = do { x ; loop x } -------------------------------------------------------------------------- instance Applicative (St s) where (<*>) = aap pure = return --------------------------------------------------------------------------