有效实施错误日志单子

时间:2019-01-22 19:18:08

标签: haskell monads state-monad

我需要一个monad,它将在计算过程中报告错误数据类型(而不是字符串)。我探索了几种不同的实现方式:

  • 一个State [Error] a monad,其中的错误与缺点(:)相加,最后我在错误列表中调用reverse以获取实际顺序。
  • 一个Writer (Endo [Error]) a monad,可以在其中添加Endo (e :)的错误。不过,我担心身份功能的所有无用串联。如果我从不添加任何错误,那么我的Endo仍将是一个由许多串联的id . id组成的大型数据结构。
  • 一个Reader (MVector s Error) (ST s a) monad,当我添加新错误时,我会在其中增加错误向量。矢量包中没有预定义的“推送”功能,因此我必须自己编写。另外,这需要我在我的某些计算中添加ST monad。

在命令式语言中,我将使用向量并调用“推”方法或等效方法,该方法将为我分摊O(1)附加值,并且结果列表的顺序正确。

对于此任务,最有效的Haskell monad实现方式(相对于命令式语言的效率)是什么?

我的某些代码在ST monad中,而我的一些代码是纯代码。对于这些不同的用例,我可以使用不同的monad。我的ST代码是否应该使用与纯代码不同的内容?

1 个答案:

答案 0 :(得分:2)

您应将日志记录monad基于StateT Seq。使用StateT,您将拥有一个monad转换器,该转换器可以将您的日志记录功能叠加在任何其他monad上。

  

我的某些代码在ST monad中,而我的一些代码是纯代码。对于这些不同的用例,我可以使用不同的monad。我的ST代码是否应该使用与纯代码不同的内容?

对于ST monad中的内容,您可以使用如上所述的monad转换器。对于纯代码而言,事情比较棘手:您将不得不将纯代码重写为monadic,或至少重写为applicative。在这一点上,它不再是纯粹的,因为日志记录是一个副作用。很难提供进一步的建议,因为我不知道您要达到什么目标。从结果类型内部的纯代码返回日志记录数据可能更有意义。