Reputation: 179
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:
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.
Is there a possibility to achieve that without manually unwrapping 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.
Upvotes: 2
Views: 923
Reputation: 15029
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".)
Upvotes: 2
Reputation: 170899
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.
Upvotes: 1
Reputation: 47072
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?
Upvotes: 3