在我的应用程序的某处,我从Parsec收到Either ParserError MyParseResult
。在下游,这个结果可以使用其他库完成其他一些解析。在第二阶段的解析过程中,也可能会出现某种错误,我希望将其作为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
但是我很惊讶没有发现任何与hackage db相匹配的内容。所以现在我怀疑我是否正在使用正确的方法处理我的问题。
为什么标准库中没有这样的功能?我的方法出了什么问题?
答案 0 :(得分:29)
我们在标准库中有这样的功能,
Control.Arrow.left :: a b c -> a (Either b d) (Either c d)
是对任意箭头的推广。将(->)
替换为a
并将其应用为中缀,以获得专业化
left :: (b -> c) -> Either b d -> Either c d
原则上你的方法没有任何问题,这是处理这种情况的明智方法。
答案 1 :(得分:17)
另一种选择是使用Either
的{{3}}实例。那你有
first :: (a -> b) -> Either a c -> Either b c
(同样Bifunctor
可用于遍历(a,b)
的第一部分。)
答案 2 :(得分:14)
使用lens:
可以轻松完成此操作import Control.Lens
over _Left (+1) $ Left 10 => Left 11
over _Left (+1) $ Right 10 => Right 10
over _Right (+1) $ Right 10 => Right 11
答案 3 :(得分:1)
另一个简单的选项是mapLeft
中的Data.Either.Combinators
:
mapLeft :: (a -> c) -> Either a b -> Either c b