说我有两个功能:
b2c :: B -> Either String C
a2bs :: A -> [[B]]
如何使用a2cs
和b2c
使以下a2bs
函数起作用,使得如果[[Either String c]]
中有Left值,则Either String [[c]]
应该是左值?
a2cs :: A -> Either String [[C]]
答案 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]]