I am a beginner in Haskell and I am working on some Haskell code that uses Either for error handling. The left element of the Either represents an error, while the right element represents a successful result. The code often uses the Applicative instance of Either, which seems to be designed for this use case.
Given an object of type [Either e r]
, what is the most elegant way to turn it into an object of type Either e [r]
? The point of this is that we might have an array of return values from some functions we called, and if any of those return values is an error, we want to get that error and throw away everything else. If multiple elements of the array have an error, I would prefer to get the left-most error if possible.
I was able to solve this problem myself in the code below by writing two functions, one of which is recursive, but is there a better way?
type Error = [Char]
myFunc :: [Either Error a] -> Either Error [a]
myFunc = myFunc2 []
myFunc2 :: [a] -> [Either Error a] -> Either Error [a]
myFunc2 r ((Left error):rest) = Left error
myFunc2 r ((Right item):rest) = myFunc2 (r ++ [item]) rest
myFunc2 r [] = Right r
main :: IO()
main = do
-- This prints: Right [1, 2, 3]
putStrLn (show (myFunc [Right 1, Right 2, Right 3]))
-- This prints: Left "division by zero"
putStrLn (show (myFunc [Right 1, Left "division by zero", Right 3]))
Use sequenceA of Data.Traversable
sequence
from Control.Monad
:
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
as in:
\> import Control.Monad (sequence)
\> sequence [Right 1, Right 2, Right 3]
Right [1,2,3]
\> sequence [Right 1, Left "division by zero", Right 3]
Left "division by zero"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With