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
withReaderT
but wherer1
andr2
are the same
To handle/modify the output of a reader computation: