该函数的名称是否定义如下:
f :: [Either a b] -> Either [a] [b]
f x = let (y1, y2) = partitionEithers x in
case y1 of
[] -> Right y2
_ -> Left y1
基本上,如果列表至少包含Left
,则返回所有Left
,否则返回所有Right
。
或者,在我错过的类型类上是否对此功能有一些概括?
答案 0 :(得分:11)
Validation
(几乎)是sequence
;您只需要将a
转换为[a]
。所以:
traverse (eitherToValidation . first pure)
如果您重写生产者以首先生产Validation
而不是Either
,则噪音会更低。
答案 1 :(得分:6)
当然可以使用任一monad来获得一个Left或Right:
Prelude> let a = [Right "hello", Right "World", Right "Bye"]
Prelude> sequence a
Right ["hello","World","Bye"]
Prelude> let a = [Right "hello", Right "World", Left "Bye"]
Prelude> sequence a
Left "Bye"
但是要获得 all 的所有Left
值,在我所知道的基础库或公共库中似乎都不是什么,因此您可能需要推出自己的解决方案。也就是说,我认为我们可以找到一种更具可读性的解决方案。我建议:
f x | any isLeft x = lefts x
| otherwise = rights x
或
f x | not (null ls) = ls
| otherwise = rs
where (ls,rs) = partitionEithers x