Haskell 使用管道(-core)的错误处理方法是什么?
我目前正在为我的一个小项目编写一些管道核心/管道。我希望每个解析器提供一个管道,它等待Haskell 使用管道(-core)的错误处理方法是什么?,haskell,error-handling,Haskell,Error Handling,我目前正在为我的一个小项目编写一些管道核心/管道。我希望每个解析器提供一个管道,它等待ByteString输入到解析器,并生成任何解析值(重新启动解析器)。如果不进行错误处理,它将具有如下类型 parserP :: Monad m => Parser a -> Pipe ByteString a m r 现在,我不确定如何处理解析错误。我目前的想法是: 将错误添加到返回类型中(即,在中返回值,而不仅仅是r) 要求monad提供错误处理机制(即要求接管管道的monad实现Monad
ByteString
输入到解析器,并生成任何解析值(重新启动解析器)。如果不进行错误处理,它将具有如下类型
parserP :: Monad m => Parser a -> Pipe ByteString a m r
现在,我不确定如何处理解析错误。我目前的想法是:
- 将错误添加到返回类型中(即,在
中返回值,而不仅仅是
)r
- 要求monad提供错误处理机制(即要求接管管道的monad实现
)MonadError
- 通过接管任何monad
的管道,强制monad提供错误机制m
- 添加参数,让用户指定行为(类似于
,并在出现解析错误时简单地绑定到这样提供的管道)(ParseError->P.Pipe ByteString a m r)
MonadError ParseError
,这似乎会导致大量簿记)。最后,我似乎不记得看到过那么多MonadError,这表明使用它有一些问题
第三种解决方案适用于我的情况,因为管道将是管道的一部分,管道中有一个用户指定的monad(IO),它不应该关心解析错误(它将网络数据解析为用户指定类型的格式)。但它似乎并不那么优雅,而且,(可能?)一旦在任何其他环境中使用,就会导致大量簿记
我还没有真正考虑过最终的解决方案,但它似乎有点复杂
如果您对这个特殊案例有任何想法,我将不胜感激(如果我偏离太远,错过了一些明显的东西,我一点也不会感到惊讶),如果您对管道(-core)/导管/三通e.t.c中错误处理的讨论有任何(或多或少相关的)参考,我将不胜感激
编辑:
另一种可能是采取一种单一的行动(而不是完全吹制的烟斗),尽管我不确定它是否只是泛化、专门化,甚至等同于第四种行动。如果可以的话,我想我可以通过这样描述选择来帮助组织大家对这一点的想法。你可以:
管道在EitherT
/error
内:
e(管道a b m)r
管道
在EitherT
/错误
外部:
管道a b(EitherT e m)rimport Control.Error
import Control.Pipe
type PipeE e a b m r = EitherT e (Pipe a b m) r
runPipeE = runPipe . runEitherT
p1 <?< p2 = EitherT (runEitherT p1 <+< runEitherT p2)
导入控制。错误
导入控制。管道
类型管道e a b m r=e(管道a b m)r
runPipe=runPipe。鲁尼瑟特
p1我要指出的是,提案3(使用error e m a
)完全包含在我个人最喜欢的提案2(使用MonadError
)中。但我真的不知道如何客观地回答这个问题。我已经给加布里埃尔发了电子邮件通知他这一点,因为他是和包的作者;大概他一直在考虑这两件事,可能是一起考虑的。@DanielWagner我同意这似乎是上述问题的最佳解决方案。问题是,我总是喜欢引入额外的类型类;尤其是对于那些不仅仅是美化运算符重载的事情。@DanBurton我刚刚意识到我以前忘记说谢谢了!:)很好地减少/简化了问题,并就在这种特殊情况下应用何种方法提出了很好的建议,完美!