Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A function from [Either a b] to Either [a] [b]

Tags:

haskell

Is there a name for the function defined as follows:

f :: [Either a b] -> Either [a] [b]
f x = let (y1, y2) = partitionEithers x in
  case y1 of
    [] -> Right y2
    _ -> Left y1

Basically if the list contains at least on Left it returns all the Lefts otherwise it returns all the Rights.

Alternatively, are there some generalisation of this function over a type class that I've missed?

like image 579
Clinton Avatar asked Apr 30 '19 01:04

Clinton


2 Answers

This is (almost) sequence for Validation; you just need to convert your as to [a]s. So:

traverse (eitherToValidation . first pure)

If you rewrite your producer to produce Validations instead of Eithers in the first place it will be even less noisy.

like image 140
Daniel Wagner Avatar answered Sep 19 '22 00:09

Daniel Wagner


Well certainly you can get a single Left or the Right using the either monad:

Prelude> let a = [Right "hello", Right "World", Right "Bye"]
Prelude> sequence a
Right ["hello","World","Bye"]
Prelude> let a = [Right "hello", Right "World", Left "Bye"]
Prelude> sequence a
Left "Bye"

But to get all the Left values doesn't seem like anything in the base or common libraries I know so you're probably left rolling your own solution. That said, I think we can find a much more readable solution. I propose:

f x | any isLeft x = lefts x
    | otherwise    = rights x

or

f x | not (null ls) = ls
    | otherwise     = rs
 where (ls,rs) = partitionEithers x
like image 34
Thomas M. DuBuisson Avatar answered Sep 21 '22 00:09

Thomas M. DuBuisson