在左边的映射

Nik*_*kov 20 haskell either

在我的应用程序的某个地方,我Either ParserError MyParseResult从Parsec 收到一个.在下游,这个结果可以使用其他库完成其他一些解析.在第二阶段的解析过程中,也可能会出现某种错误,我希望将其作为a传递Left String,但为此我需要将结果从Parsec转换为String.为了实现这一点,我需要一个允许我Left使用show函数映射a 的函数.

我想的映射函数看起来像这样:

mapLeft :: (a -> b) -> Either a c -> Either b c
mapLeft f (Left x) = Left $ f x
mapLeft _ x = x
Run Code Online (Sandbox Code Playgroud)

但我很惊讶没有发现任何与hackage db相匹配的东西.所以现在我怀疑我是否正在使用正确的方法解决我的问题.

为什么标准库中没有这样的功能?我的做法有什么问题?

Dan*_*her 32

我们在标准库中有这样的功能,

Control.Arrow.left :: a b c -> a (Either b d) (Either c d)
Run Code Online (Sandbox Code Playgroud)

是对任意箭头的推广.替代(->)a和缀应用它,以获得专业化

left :: (b -> c) -> Either b d -> Either c d
Run Code Online (Sandbox Code Playgroud)

原则上你的方法没有任何问题,这是处理这种情况的明智方法.

  • 在最近的版本中它是"over _left" - 以防有人稍后遇到这个问题. (5认同)
  • `lens`也提供这个功能,名称为`over traverseLeft`. (4认同)

Pet*_*lák 19

另一种选择是使用Bifunctor实例Either.那你有

first :: (a -> b) -> Either a c -> Either b c
Run Code Online (Sandbox Code Playgroud)

(也Bifunctor可用于遍历第一部分(a,b).)

  • @NikitaVolkov我对此也很好奇,我发现[Hoogle搜索:数组,箭头,base,bytestring,Cabal,cgi,容器,目录,文件路径,haskell-src,HUnit,mtl,old-locale,old- time,packedstring,parallel,parsec,pretty,process,QuickCheck,random,stm,template-haskell,time,xhtml](http://www.haskell.org/haskellwiki/Hoogle#Scope_of_Web_Searches).可能需要创建一个完整的本地数据库来搜索所有Hackage库. (3认同)

Joh*_*ley 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
Run Code Online (Sandbox Code Playgroud)