What you want is to "run the []
under the StateT
" so to speak, obtaining all the Int
results of anyFunction
, while preserving the rest of the monad stack as much as possible.
You would like a function with a type similar to StateT Int [] Int -> State Int [Int]
. That gets all the Int
s so that you can calculate the maximum.
But given your monad stack, your function is difficult to implement. Each branching path of the computation has its own "thread" of state, but when you reduce a StateT Int [] Int
to a State Int [Int]
, which "thread" of state should we keep? There's no solution that looks natural.
Now, imagine that you are working with a ListT (State Int) Int
monad stack instead. Here all branches share the same "thread" of state. Specializing runListT
, it has the signature ListT (State Int) Int -> State Int [Int]
.
The example could be written as follows:
anyFunction :: ListT (State Int) Int
anyFunction = undefined
test :: ListT (State Int) Int
test = do
-- preserve non-ListT parts of the stack
-- and re-wrap the result into a list
s <- ListT $ liftM (\l -> [maximum l]) $ runListT anyFunction
put s
v <- get
if even v then return v else mzero