Week 4 Lecture 1
hs
1import Control.Monad (ap, liftM, void, (<=<), (>=>))2import Data.IORef (IORef, newIORef, readIORef, writeIORef)34-- What do I owe you?5-- Nothing, it's for free!6-- Monads? For freee????!78-- I guess I'm forced to write haskell the old fashioned way now -- Writing with a bat? A butterfly910newtype FState s a = FState {runFState :: s -> (a, s)}1112instance Functor (FState s) where13 fmap = liftM1415instance Applicative (FState s) where16 -- pure x = FState $ \s -> (x, s)17 -- pure x = FState $ (x,)18 pure = FState . (,)19 (<*>) = ap2021instance Monad (FState s) where22 c >>= f = FState $ \s ->23 let (a, s') = runFState c s24 in runFState (f a) s'2526get :: FState s s27get = FState (\s -> (s, s))2829put :: s -> FState s ()30-- put s = FState (\_ -> ((), s))31-- put s = FState (const ((), s))32put = FState . const . ((),) -- ~~Pointless!~~ Pointfree! -.-3334-- The get, put and runState functions define the State monad35-- Alongside the following rules:36-- put s >> get = put s >> return s37-- put s >> put s' = put s'38-- get >>= put = return ()3940-- type Monad :: (* -> *) -> Constraint41-- class Applicative m => Monad m where42-- ...43-- (>>) :: m a -> m b -> m b44-- ...45-- -- Defined in ‘GHC.Internal.Base’46-- infixl 1 >>4748-- yee 🦕 Dino nuggies, omg i want dino nuggies4950class (Monad m) => StateMonad m s where51 getm :: m s52 putm :: s -> m ()5354modify :: (StateMonad m s) => (s -> s) -> m ()55-- modify f = getm >>= (putm . f)56modify f = f <$> getm >>= putm5758tick :: (StateMonad m Int) => m Int59-- tick = do{n <- getm; putm (n+1); return n}60tick = do n <- getm; n <$ putm (n + 1)6162push :: (StateMonad m [a]) => a -> m ()63push x = modify (x :)6465pop :: (StateMonad m [a]) => m (Maybe a)66pop =67 do68 xs <- getm69 case xs of70 [] -> return Nothing71 (x : xs') -> do putm xs'; return $ Just x7273newtype IState s a = IState {runIState :: IORef s -> IO a}7475evalIState :: s -> IState s a -> IO a76evalIState def m = newIORef def >>= runIState m7778instance Functor (IState s) where79 fmap = liftM8081instance Applicative (IState s) where82 pure = IState . const . pure83 (<*>) = ap8485instance Monad (IState s) where86 c >>= f = IState $ \ref -> do87 val <- runIState c ref88 runIState (f val) ref8990instance StateMonad (IState s) s where91 getm = IState $ readIORef92 putm = IState . flip writeIORef9394-- A `continuation` is passed into the function95-- Continuation passing style!96putk :: (StateMonad m s) => s -> (() -> m a) -> m a97putk s = (putm s >>=)9899data FSM s a where100 Return :: a -> FSM s a101 Getk :: (s -> FSM s a) -> FSM s a102 Putk :: s -> FSM s a -> FSM s a103104instance Functor (FSM s) where105 fmap = liftM106107instance Applicative (FSM s) where108 pure = Return109 (<*>) = ap110111instance Monad (FSM s) where112 Return x >>= f = f x113 Getk n >>= f = Getk $ \s -> n s >>= f -- GetK (n >=> f)114 Putk v n >>= f = Putk v $ n >>= f -- PutK ()115116instance StateMonad (FSM s) s where117 getm = Getk return118 putm state' = Putk state' (return ())119120-- This function allows FSM to be evaluated under any other StateMonad121evalFSM :: (StateMonad m s) => FSM s a -> m a122evalFSM (Return x) = return x123evalFSM (Getk next) = getm >>= \state -> evalFSM (next state)124evalFSM (Putk state' next) = putm state' *> evalFSM next125126runFSM :: s -> FSM s a -> (a, s)127runFSM s (Return a) = (a, s)128runFSM s (Getk n) = runFSM s (n s)129runFSM s (Putk s' n) = runFSM s' n130131-- I'm not sure I get why these constructors are needed. Which one?132-- FSM itself, there are just the functions as constructors133-- Exactly! FSM is a Free State Monad that encodes what a state typeclass would have, but inside a datatype134-- So you can have a type that models state, but in the end you can evaluate it however you actually want135136data StateOp s a where137 StateGet :: (s -> a) -> StateOp s a138 StatePut :: s -> a -> StateOp s a139140data Free e a where141 Pure :: a -> Free e a142 Free :: e (Free e a) -> Free e a143144instance (Functor e) => Functor (Free e) where145 fmap = liftM146147instance (Functor e) => Applicative (Free e) where148 pure = Pure149 (<*>) = ap150151instance (Functor e) => Monad (Free e) where152 (Pure a) >>= f = f a153 (Free c) >>= f = Free $ fmap (>>= f) c154155type FreeState s a = Free (StateOp s) a156157-- Space