25

私のアプリのどこかで、Either ParserError MyParseResultParsecからを受け取ります。この結果の下流では、他のライブラリを使用して他の解析が実行されます。解析のその第2フェーズ中に、ある種のエラーが発生する可能性があります。これをとして渡したいのですLeft Stringが、そのためには、結果をParsecからStringも変換する必要があります。Leftこれを実現するには、関数を使用してマップを作成できる関数が必要ですshow

私が考えているマッピング関数は次のようになります。

mapLeft :: (a -> b) -> Either a c -> Either b c
mapLeft f (Left x) = Left $ f x
mapLeft _ x = x

しかし、私はhackagedbに一致するものが見つからなかったことに非常に驚いていました。だから今、私は自分の問題に対して正しいアプローチを使用しているかどうか疑問に思っています。

標準ライブラリにそのような関数がないのはなぜですか?私のアプローチの何が問題になっていますか?

4

4 に答える 4

36

標準ライブラリにはそのような関数がありますが、

Control.Arrow.left :: a b c -> a (Either b d) (Either c d)

任意の矢印への一般化です。スペシャライゼーションを取得するには、代わり(->)a中置を適用します

left :: (b -> c) -> Either b d -> Either c d

原則としてあなたのアプローチに問題はありません、それは状況を処理するための賢明な方法です。

于 2012-11-22T00:02:54.050 に答える
21

別のオプションは、Bifunctorのインスタンスを使用することですEither。その後、あなたは持っています

first :: (a -> b) -> Either a c -> Either b c

Bifunctorの最初の部分をトラバースするためにも使用できます(a,b)。)

于 2012-11-22T08:11:33.253 に答える
14

これはレンズで簡単に行うことができます:

import Control.Lens

over _Left (+1) $ Left 10   => Left 11
over _Left (+1) $ Right 10  => Right 10
over _Right (+1) $ Right 10 => Right 11
于 2012-11-22T05:45:54.313 に答える
4

別の簡単なオプションは次mapLeftData.Either.Combinatorsとおりです。

mapLeft :: (a -> c) -> Either a b -> Either c b
于 2018-06-07T17:54:59.793 に答える