I currently have two monads who share the same types, implemented similar to a State
monad:
newtype FooRead a = FooRead { runFooRead :: Context -> (a,Context) }
newtype FooWrite a = FooWrite { runFooWrite :: Context -> (a,Context) }
The difference between them is that the first only allows reading of the context (bind will not change it), while the second allows editing the context as well.
There are then functions who use the context in FooRead
to compute some value without changing the state of the context:
getVal :: FooRead a
getVal = do x <- ...
return x
Now I want to execute one of these reading functions from code in the writer monad:
writeFunc :: FooWrite ()
writeFunc = do x <- liftVal getVal
...
Where liftVal :: FooRead a -> FooWrite a
is a function that extracts the value returned by the FooRead
function and rolls it into a FooWrite
monad. This is all good.
However, I can not figure out a way to roll the execution of getVal
in the above into the context from my FooWrite
monad. With the above implementation, getVal
will be run in an empty instance of the monad.
I can figure out how to construct a FooRead
instance using a FooWrite
context as
lower :: FooWrite a -> FooRead a
Essentially I want to demote my writer to a reader, execute code within the reader, the re-promote it to a writer.
But not how to actually execute code within this monad?
FooReadT
(orFooWriteT
) and extend your monadFooWrite
(orFooRead
) – wit