main :: IO () main = let x = runState gibberFn1 3 y = runState gibberFn2 3 z = runState gibberFn2 3 in print x >> print y >> print z gibberFn1 :: State Int String gibberFn1 = do x <- get put (x+1) y <- get return $ show (y+1) gibberFn2 :: State Int String gibberFn2 = get >>= \x -> put (x+1) >>= \_ -> get >>= \y -> return $ show (y+1) gibberFn3 :: State Int String gibberFn3 = State $ \s -> let -- get >>= \x -> (State ftemp1) = get (x, s') = ftemp1 s -- put (x+1) >>= \_ -> (State ftemp2) = put (x+1) (_, s'') = ftemp2 s' -- get >>= \y -> (State ftemp3) = get (y, s''') = ftemp3 s'' -- return $ show (y+1) in (show y, s''') newtype State s a = State (s -> (a, s)) runState (State f) a = f a get = State (\s -> (s,s)) put x = State (\s -> ((), x)) instance Functor (State s) where -- fmap :: (a -> b) -> State a _ -> State b _ fmap f (State g) = State (\x -> let (op', s') = g x in (f op', s')) instance Applicative (State s) where -- pure :: a -> State s a pure a = State $ \s -> (a, s) -- <*> :: State s (a -> b) -> State s a -> State b (State f) <*> (State g) = State $ \s -> let (f', s') = f s (a'', s'') = g s' in (f' a'',s'') instance Monad (State s) where return = pure -- (>>=) :: State s a -> (a -> State s b) -> State s b (State f) >>= g = State $ \s -> let (a', s') = f s (State h) = g a' in h s'