State-like Transformers
ReaderT
, StateT
, and WriterT
can all be used to simulate state manipuation effects.
ReaderT
can "modify state" in a top-down direction via MonadReader
's local
function:
foo :: Reader Int Int
foo = do
local (_ + 1) do
local (_ + 1) do
local (_ + 1) do
local (_ + 1) do
stateAtThisPoint <- ask
pure stateAtThisPoint
bar = foo 0 -- 0 + 1 + 1 + 1 + 1 == 4
WriterT
can "modify state" in a bottom-up direction via MonadTell
's tell
function
foo :: Int -> WriterT (Array (Array String)) Int
foo i
| i == 3 = pure 3
| otherwise = do
y <- foo (i + 1)
tell [[ y ]]
bar = foo 0 -- Tuple 1 [ [3], [2], [1] ]
{-
which breaks down to...
bar = do
one <- do
two <- do
three <- pure 3
tell [ [ three ] ]
tell [ [ two ] ]
tell [ [ one ] ]
-}
StateT
can "modify state" in a top-down and/or bottom-up direction via MonadState
's get
/put
/modify
functions.
See also What is the difference between ST effect / Reader / Writer ?