如何检查Haskell中一种代数类型列表中的所有元素?

Sau*_*ade 4 haskell functional-programming haskell-platform

如果我有以下代数数据类型

type MyVal = Either String Int
Run Code Online (Sandbox Code Playgroud)

并具有包含MyVal类型的元素的列表

ls = [Right 1, Right 2, Right 3]
xs = [Right 1, Left "error", Right 3]
Run Code Online (Sandbox Code Playgroud)

现在,我想写函数找出那是我所有具有“ Right”值的列表,然后它应该返回True,否则返回False。

在这种情况下,ls它将返回True,xs并且将返回False。

我怎样才能做到这一点?

我尝试使用all函数,但无法正确使用它。

pig*_*ker 19

不能否定all isRight一个很好的回答这是问的问题,我会问这个问题,在一定程度上。计算a列表中的Bool所有Either值是否有什么好处Right?它使您能够做什么?一个答案是,它使您有权Right从整个列表中剥离标签,将整个标签视为无错误。

一个更有用的选择可能是构造某种类型的东西

[Either String Int] -> Either String [Int]
Run Code Online (Sandbox Code Playgroud)

因此,您可以获得所有不带标签的消息或与第一个烦恼相关的消息,而不是单纯的True或。FalseIntLeft

并且有一个标准函数可以执行此操作(以及其他许多功能)。它利用了一个事实,即列表是具有标准遍历模式的数据结构,并且Either String使用标准的失败和成功传播模式来编码错误管理计算的概念。该类型已经完成了艰苦的工作。您只需要说...

sequenceA
Run Code Online (Sandbox Code Playgroud)


Wil*_*sem 6

您可以使用该isRight :: Either a b -> Bool函数检查Either a b值是否为Right x

因此,您可以使用以下方法实现此目的:

import Data.Either(isRight)

allRight :: Foldable f => f (Either a b) -> Bool
allRight = all isRight
Run Code Online (Sandbox Code Playgroud)

这给了我们预期的输出:

Prelude Data.Either> allRight ls
True
Prelude Data.Either> allRight xs
False
Run Code Online (Sandbox Code Playgroud)