I will try to give the most simplified conceptual example of my problem. Hope there is nothing reprehensible in this. I think in this form the question will be more general and useful.
I encountered a problem and solved it. But the method I used looks a little terrible. I want some guidance on how to achieve the effect I’ve described, but in the right way.
Simplified example
Perhaps it is called differently, because… my nested Reader
strictly speaking is not a transformer, but consider the following monad stack:
type MyStack a = MaybeT (Reader String) a
-- ~ String -> Maybe a
-- This is correct order, right? `Reader` is the base monad.
and the value:
produce :: MyStack Int
produce = MaybeT $ Reader $ \n -> Just (read n)
I’m trying to access an input value of Reader
inside a function like this
compute :: MyStack Int
compute = do
let pack = MaybeT . Reader
unpack = runReader . runMaybeT
modify fn = \inp -> (,) inp <$> fn inp -- ~ `Just (inp, read inp)`
(inp, out) <- pack . modify . unpack $ produce
-- computatons involving `inp` and `out`
I guess this is the wrong approach, but nothing else comes to mind.
Сould anyone point me to how this should be done correctly, please?
Sorry if there are typos or misleadings in some places. I tried to simplify the example as much as possible and may have made mistakes. It is also very likely that I understand something completely wrong and describe nonsense. You can point this out to me and I will try to correct or supplement the question.
Please do not judge harshly. I’m far from a professional and not trying to seem like one.
P.S. You may notice that it looks like I’m trying to temporarily turn Reader
into State
. You can also advise me to use it this way:
type MyStack a = MaybeT (State String) a
produce :: MyStack Int
produce = MaybeT $ State \s -> (Just (read s), s)
compute :: MyStack Int
compute = do
res <- produce
stt <- get
-- computatons involving `inp` and `stt`
But I can’t change the stack definition in my situation. This is the limitation given in this question.