在Haskell中编写firstRightOrLefts的惯用法?

时间:2014-11-05 19:57:29

标签: haskell either

我有以下方法:

firstRightOrLefts :: [Either b a] -> Either [b] a
firstRightOrLefts eithers = 
   case partitionEithers eithers of
      (_,  (x : _)) -> Right x
      (xs, _)       -> Left xs

困扰我的是丑陋的模式匹配,我想知道是否有更惯用的方式来编写这种方法。我的想法是,我有一堆可以返回Eithers的计算,我只想获得第一个结果或所有错误消息。也许我使用了错误的数据结构。也许Writer monad会更适合这项任务。我现在真的不确定。欢呼任何帮助!

2 个答案:

答案 0 :(得分:17)

反向约定实际上只是Either的monad定义,sequence的定义适用于此:

ghci> :t sequence :: [Either a b] -> Either a [b]
sequence :: [Either a b] -> Either a [b]
  :: [Either a b] -> Either a [b]

要将此实际应用于您的案例,我们需要一个函数flipEither:

firstRightOrLefts = fe . sequence . map fe
    where fe (Left a) = Right a
          fe (Right b) = Left b

答案 1 :(得分:9)

ExceptMonadPlus实例有此行为:

import Control.Monad
import Control.Monad.Trans.Except

firstRightOrLefts :: [Either e a] -> Either [e] a
firstRightOrLefts = runExcept . msum . fmap (withExcept (:[]) . except)