Overview
Monad Reader
MonadAsk is used to expose a read-only value to a monadic context. It's default implmentation is ReaderT:
-- r m a
newtype ReaderT readOnly monad finalOutput =
ReaderT (\readOnly -> monad finalOutput)
-- Pseudo-syntax for combining the type class and ReaderT's instance together
class (Monad m) <= MonadAsk r (ReaderT r m) where
ask :: forall a. ReaderT r m a
ask a = ReaderT (\_ -> pure a)
Do Notation
When writing StateT's do notation, we have a function called get that does not take any argument but still returns a value:
stateManipulation :: State Int Int
stateManipulation =
get
-- which reduces to
state (\s -> Tuple s s)
-- which reduces to
StateT (\s -> Identity (Tuple s s))
-- When we run `stateManipulation` with `runState`...
runState (StateT (\s -> Identity (Tuple s s))) 0
-- it reduces to...
unboxIdentity $ (\s -> Identity (Tuple s s)) 0
-- which reduces to
unboxIdentity (Identity (Tuple 0 0))
-- and finally outputs
Tuple 0 0
MonadAsk's function works similarly:
type Settings = { editable :: Boolean, fontSize :: Int }
useSettings :: Reader Settings Settings
useSettings = ask
-- which reduces to...
ReaderT (\r -> Identity r)
-- When we run `useSettings` with `runReader`
runReader useSettings { editable: true, fontSize: 12 }
-- it reduces to
unwrapIdentity $ (\r -> Identity r) { editable: true, fontSize: 12 }
-- which reduces to
unwrapIdentity (Identity { editable: true, fontSize: 12 })
-- which reduces to
{ editable: true, fontSize: 12 }
MonadReader
MonadReader extends MonadAsk by allowing the read-only value to be modified first before being used in one computation.
class MonadAsk r m <= MonadReader r m | m -> r where
local :: forall a. (r -> r) -> m a -> m a
Derived Functions
MonadReader does not have any derived functions.
MonadAsk has one derived function:
asks: apply a function to the read-only value (useful for extracting something out of it, like a field in a settings object)
Laws, Instances, and Miscellaneous Functions
For the laws, see
To see how ReaderT implements its instances
- Functor instance
- Apply instance
- Applicative instance
- Bind instance
- MonadTell instance, which is implemented using
pure(Applicative) - MonadReader instance, which is implemented using
withReaderTbut wherer1andr2are the same
To handle/modify the output of a reader computation: