# Is there a better way to apply a filter over an Either right value?

Suppose you have an IO (Either String (String, [Int])) and you want to filter the [Int].

Let's say we want to use the following filter:

:t filter even
Integral a => [a] -> [a]


As far as I understand we need to lift the function filter even to be applied to an IO (Either String, (String, [Int])), so I did:

:t (fmap . fmap . fmap . filter) even
(Functor f1, Functor f2, Functor f3, Integral a) => f1 (f2 (f3 [a])) -> f1 (f2 (f3 [a]))


I know this symbol exists <$> (take a look here), but I don't want to add that dependency. Here is the full example: --- You can paste this in GHCi ioe = pure$ Right ("a,b,c,d", [1,2,3,4]) :: IO (Either String (String, [Int]))
(fmap . fmap . fmap . filter) even ioe
-- return: Right ("a,b,c,d",[2,4])


It works, but I wonder: is there a better way to do it?

While (fmap . fmap . fmap . filter) even is certainly possible, there is a function for Either in Control.Arrow called right. The same module also contains second, which works on the second part of a pair.

right  :: (b -> c) -> Either a b -> Either a c
second :: (b -> c) ->     (a, b) ->     (a, c)


The actual types use Arrow or ArrowChoice, but it basically boils down to this. With those functions, you can write (fmap . fmap . fmap . filter) even ioe as

(right . second . filter) even <\$> ioe
-- or
(fmap . right . second . filter) even ioe
`

However, the behavior doesn't differ from your original variant.

Note that there are several libraries that provide lenses and enable you to write code in a similar way.