I am stuck with following monad problem:
Let's say I have a standard monad State with state S = (LS, RS). I also have another monad:
newtype StateP a = StateP {runP :: S -> (a, RS)}
I want to perform some computation using StateP then merge state with state in State monad:
merge m :: StateP() -> State()
merge m = do
s@(l,r) <- get
put (l, snd (runP m s))
It is not working, but I don't get why? Is there another way to achieve such functionality?
You can use monad transformers to model these requirements more explicitly using two monad stacks: one that can only read LS
and one that can both read and write LS
.
type ReadOnlyLS a = ReaderT LS (State RS) a
type ReadWriteLS a = StateT LS (State RS) a
To run a ReadOnlyLS
within ReadWriteLS
, we just need to extract LS
from the outermost state layer, give it to the reader layer of the inner computation and lift the resulting computation back into the outer monad:
merge :: ReadOnlyLS a -> ReadWriteLS a
merge m = get >>= lift . runReaderT m