我有以下方法:
firstRightOrLefts :: [Either b a] -> Either [b] a
firstRightOrLefts eithers =
case partitionEithers eithers of
(_, (x : _)) -> Right x
(xs, _) -> Left xs
困扰我的是丑陋的模式匹配,我想知道是否有更惯用的方式来编写这种方法。我的想法是,我有一堆可以返回Eithers的计算,我只想获得第一个结果或所有错误消息。也许我使用了错误的数据结构。也许Writer monad会更适合这项任务。我现在真的不确定。欢呼任何帮助!
答案 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)
Except
的MonadPlus
实例有此行为:
import Control.Monad
import Control.Monad.Trans.Except
firstRightOrLefts :: [Either e a] -> Either [e] a
firstRightOrLefts = runExcept . msum . fmap (withExcept (:[]) . except)