views:

137

answers:

3

I have a f function 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.

+1  A: 

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?

Dave Hinton
oh yeah, you're right - thx :) I mixed up the type of the underlying monad and the result type of the computation.
haselhorstk
+1  A: 

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.

Alexey Romanov
A: 

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".)

Reid Barton