10

私は次の方法を持っています:

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

私を悩ませているのは醜いパターンマッチングであり、このメソッドを書くためのより慣用的な方法があるかどうか疑問に思っていました. アイデアは、Eithers を返すことができる一連の計算があり、最初の結果またはすべてのエラー メッセージを取得したいということです。間違ったデータ構造を使用している可能性があります。おそらく Writer モナドがこのタスクにより適しているでしょう。現時点ではよくわかりません。どんな助けにも乾杯!

4

2 に答える 2

18

逆の規則は、実際には のモナド定義でEitherあり、 の定義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
于 2014-11-05T20:13:18.887 に答える
9

MonadPlusインスタンスの動作Exceptは次のとおりです。

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

firstRightOrLefts :: [Either e a] -> Either [e] a
firstRightOrLefts = runExcept . msum . fmap (withExcept (:[]) . except)
于 2014-11-05T20:12:58.970 に答える