monad tranformers and stacking of multiple monads
I have function f
with signature f :: [a] -> StateT Int Reader b [c]
, and f'
with signature f' :: a -> StateT Int Reader b [c]
The computation in f (very simplified) looks like that:
开发者_Go百科f [] = return []
f (s:st) = f' s >>= \x ->
f st >>= \y ->
return $ ...
And in place of the ... I would like to return the [c]
part of x
++
the [c]
part of y
with the monad stuff wrapped around.
x
and y
and manually put the result together again? Do I need a List monad at the bottom of my monad stack to get simple code? The Reader Monad is obviously not an instance of the MonadPlus class.I don't get what you mean by unwrapping x
and y
.
I would have the last line as
return (x ++ y)
Do I misunderstand what you want?
You can also simply define
f = fmap concat . mapM f'
(mapM f' xs
produces a value of type m [[c]]
, where xs :: [a]
and m = StateT Int (Reader b)
, and then fmap concat
concatenates the lists "inside the monad".)
Both f' s
and f st
are values in one monad, namely StateT Int Reader b
. So you already have x :: [c]
and y :: [c]
and you just need to write return (x ++ y)
, as Dave Hinton said.
精彩评论