## Filtering a list of monads

I am attempting to filter a list of type: `IO [Either a b]`

Ideally, I would like to compose filtering function with the following type sig:

```
(Monad m, Monad m2) => m [m2 a] -> (a -> Bool) -> m [m2 a]
```

I have tried a lot of combinations of `filter`

, `filterM`

, `fmap`

, and `=<<`

in a vain attempt to lift my predicate into the proper context, but I keep missing the mark - I can achieve `m [m a]-> (a -> m Bool)-> m [m a]`

, but since Either and IO are not the same monad, this doesn't seem to do me any good.

This seems like a usecase for 'do notation' , but I've been unable to suss out a way to examine the type signatures of things assigned with the `<-`

operator, and so am left shooting at a moving target.

I am not sure how to compose the function in a way that will make it clear that it's traversing a list containing a instances of a different monad (Either) then the monad that contains the list itself (IO).

What am I missing here?

Show source

## Answers ( 2 )

It can't be done in general, because the

`Monad`

interface provides no way to get an`a`

out of an`m a`

. You can get as far as`m [m2 Bool]`

using`fmap (fmap (fmap f))`

but you need to get the`Bool`

out of the`m2 Bool`

in order to decide whether or not to drop the element.Look at it this way. What if the monad in question was

`Proxy`

?You can't look at the

`Bool`

inside a`Proxy Bool`

because there's never anything inside it! Given`a -> Bool`

and`[Proxy a]`

, how can I be expected to know which elements of the list to drop?You

canwrite a function with the following type signature:Note that the return type is

`f (g [a])`

, not`f [g a]`

.This function uses

`fmap`

to go into the outer functor, smashes together the applicative`g`

s in the list, then`fmap`

s once more to filter the results.To add to the accepted answer while you may not be able to get the

`a`

out of the`Monad m`

, you can get your functions into the`Monad m`

using e.g.`liftM`

. Depending on the inner structure(s) you can still compose usable actions and then finally sequence them in some fashion so the computations 'happen' in the desired fashion.To give an example using the problem of

`IO[Either a b]`

given as`IO[Either Bool Integer]`

: