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

How to check if all the element in the list of one algebraic type in Haskell?

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

type MyVal = Either String Int

并且有一个包含 MyVal 类型元素的列表

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

现在,我想编写函数来找出我的列表是否具有 'Right' 的所有值,然后它应该 return 为 True,否则为 False。

ls 的情况下它将 return True 而对于 xs 它将 return False.

我该怎么做?

我试过使用 all 功能,但无法正确使用。

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

因此您可以通过以下方式实现:

import Data.Either(isRight)

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

这给了我们预期的输出:

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

不要否定 all isRight 作为对所提问题的一个很好的回答,我会在某种程度上质疑这个问题。作为 Bool,计算列表中的所有 Either 值是否都是 Right 有什么好处?它使您能够做什么?一个答案是它允许您从整个列表中删除 Right 标签,将整个列表视为没有错误。

一个信息量更大的选择可能是构造一些类型

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

这样您就可以获得所有未标记的 Int 或与第一个讨厌的 Left 关联的消息,而不是单纯的 TrueFalse

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

sequenceA