I have a function which returns a list of Either items. If it only contains Right items I want to return a single Right containing a list of the values in the original Right items, but if it contains any Left items I want a single Left containing a list of the values in the original Left items. So if I have:
[Right "a", Right "b", Right "c"]
it should become:
Right ["a", "b", "c"]
but if I have:
[Right "a", Left "b", Right "c", Left "d"]
it should become:
Left ["b", "d"]
Note: The sequence function from Control.Monad isn't suitable because it only keeps the first Left item.
I have come up with this:
eitherList :: [Either a1 a2] -> Either [a1] [a2]
eitherList l = if null lefts
then Right rights
else Left lefts
where f1 (Left a) (al, ar) = (a : al, ar)
f1 (Right a) (al, ar) = (al, a : ar)
(lefts, rights) = foldr f1 ([], []) l
but it seems clumsy. Is there a simpler or better way of doing this? I'm just starting to learn about functors and monads and I'm wondering if these are relevant?