如何将[[[Either String c]]]转换为`Either String [[c]]`?

时间:2018-12-11 15:57:37

标签: haskell

说我有两个功能:

b2c :: B -> Either String C
a2bs :: A -> [[B]]

如何使用a2csb2c使以下a2bs函数起作用,使得如果[[Either String c]]中有Left值,则Either String [[c]]应该是左值?

a2cs :: A -> Either String [[C]]

3 个答案:

答案 0 :(得分:6)

我会这样写:

a2cs = traverse (traverse b2c) . a2bs

尽管这并没有完全使用您建议的实施策略,即首先生成[[Either String C]],然后将其展平为Either String [[C]],但它的优点是只需要对嵌套列表进行一次遍历,而不是您的策略需要这两个。

答案 1 :(得分:5)

您可以为此使用sequence,但这不是一个简单的步骤。它将一对类型构造函数的层换向,但是您需要将Either String构造函数移出两个类型层。好吧,我们的老朋友map派上了用场。

foo1 :: [[Either String c]] -> [Either String [c]]
foo1 = map sequence

然后继续进行其他操作:

foo2 :: [Either String [c]] -> Either String [[c]]
foo2 = sequence

如果您想变得更紧凑,可以将其与函数组成结合在一起:sequence . map sequence :: [[Either String c]] -> Either String [[c]]

答案 2 :(得分:3)

首先将您的[[Either String c]]转换为[Either String [c]],然后将其转换为Either String [[c]],如下所示:

func = sequence . map sequence

func [[Right 1, Right 2], [Left "a"]]
> Left "a"

func [[Right 1, Right 2], [Right 3]]
> Right [[1,2][3]]