PFP Laboratory 8
Jump to navigation
Jump to search
Monads
- Create a type
type SimpleState s a = s -> (s, a)
Implement the monadic functions return
and bind
retSt :: a -> SimpleState s a
retSt a = \s -> (s,a)
readInt :: ListInput Int
readInt stateList = (tail stateList, head stateList)
bind :: (s -> (s,a)) -- step
-> (a -> (s -> (s, b))) -- makeStep
-> s -> (s, b) -- (makeStep result) newState
bind step makeStep oldState =
let (newState, result) = step oldState
in (makeStep result) newState
- Define a new type and a function:
type ListInput a = SimpleState [Int] a
readInt :: ListInput Int
readInt stateList = (tail stateList, head stateList)
Use the previously defined functions to bind actions readInt
.
- Consider you have a type:
newtype State s a = State { runState :: s -> (s, a) }
Make this type the instance of Monad
newtype State s a = State { runState :: s -> (s, a) }
instance Functor (State s) where
fmap f m = State $ \s-> let (s',a) = runState m s in (s',f a)
instance Applicative (State s) where
pure a = State (\s->(s,a))
f <*> m = State $ \s-> let (s',f') = runState f s
(s'',a) = runState m s' in (s'',f' a)
instance Monad (State s ) where
return a = State (\s->(s,a))
m >>= k = State $ \s -> let (s',a) = runState m s in runState (k a) s'
- Define a function
readInt'
, so that following code will be valid:
add :: State [Int] Int
add = do x<-readInt'
y<-readInt'
return (x+y)
readInt' :: State [Int] Int
readInt' = State {runState = \s->(tail s, head s)}