5
votes

If I have following algebraic data type

type MyVal = Either String Int

and have a list containing element of type MyVal

ls = [Right 1, Right 2, Right 3]
xs = [Right 1, Left "error", Right 3]

now, I want write function to find out that is my list having all the value of 'Right' then it should return True otherwise False.

In case of ls it will return True and for xs it will return False.

How can I do that?

I have tried using all function but could not able to use it correctly.

2
@Saurabhkukade Then it is a type alias instead of algebraic data type.Nikita Volkov

2 Answers

21
votes

Not to gainsay all isRight as a good answer to the question which was asked, I'd question the question, to some extent. What good is it to compute, as a Bool, whether all the Either values in a list are Right? What does it enable you to do? One answer is that it entitles you to strip the Right tags from the entire list, treating the whole as error free.

A more informative option might be to construct something of type

[Either String Int] -> Either String [Int]

so that instead of a mere True or False, you obtain all the Ints untagged or the message associated with the first pesky Left.

And there is a standard function which does this (and many other things besides). It exploits the fact that lists are a data structure with a standard traversal pattern and that Either String encodes a notion of error-managing computation with standard patterns of failure and success propagation. The type has already done the hard work. All you need to say is...

sequenceA
6
votes

You can make use of the isRight :: Either a b -> Bool function to check if an Either a b value is a Right x.

So you can implement this with:

import Data.Either(isRight)

allRight :: Foldable f => f (Either a b) -> Bool
allRight = all isRight

This gives us the expected output:

Prelude Data.Either> allRight ls
True
Prelude Data.Either> allRight xs
False