从[E ab b]到[a] [b]的函数

时间:2019-04-30 01:54:39

标签: haskell

该函数的名称是否定义如下:

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

或者,在我错过的类型类上是否对此功能有一些概括?

2 个答案:

答案 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