3

まず、次Eitherのように生成される s の(無限の) リストがあります。

x :: A
...

f :: A -> Either B A
...

xs :: [Either B A]
xs = iterate (>>=f) (Right x)

リストにはいくつかRightの s (常に有限数) が含まれ、同じLeft値が繰り返されます。私が必要とするのは、すべてのRights とLeftそれらの後に 1 つを取ることです。この特定のケースでは、たとえば関数を変更することでも実行できますが、最善の一般的な方法にも興味があります。

4

3 に答える 3

9

より侵襲的な変更を提案させてください。それ以外の

x :: A
f :: A -> Either B A
xs :: [Either B A]

検討

x :: A
f :: A -> Writer [A] B

xsそして完全に忘れます。以前fは反復の単一ステップでしたが、現在は再帰的です。それが戻る前にRight a、あなたは今tell [a] >> f a; 戻る前にLeft b、あなたは今return b

本当に必要な場合は、 の個々の部分Writer、つまり[A]Bを経由execWriterしてevalWriter(または を使用runWriterして両方に一度にアクセスすることで) アクセスできます。

xs :: [A]
b :: B
(xs, b) = runWriter (f x)
于 2012-10-16T20:22:48.290 に答える
5

を使用して要素と要素spanの間でリストを分割し、次にパターン マッチを使用して最初の を取得できます。RightLeftLeft

(rights, firstLeft : _) = span isRight xs
    where isRight (Right _) = True
          isRight _         = False
于 2012-10-16T18:39:38.183 に答える
1

それらをすべて同じリストに保持する必要がある場合は、次のようにします。

answer = map fst . takeWhile snd $ zip xs (True : map isRight xs)
  where isRight (Right _) = True
        isRight _         = False

( Data.EitherisRightで定義されていないのはなぜですか?)isLeft

于 2012-10-16T19:30:33.950 に答える