【问题标题】:Efficient implementation of an error log monad错误日志单子的有效实现
【发布时间】:2019-01-22 19:18:08
【问题描述】:

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

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

在命令式语言中,我会使用向量并调用“push”方法或等效方法,这将给我摊销 O(1) 附加,结果列表将按正确的顺序排列。

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

我的一些代码在 ST monad 中,而我的一些代码是纯代码。对于这些不同的用例,我可以使用不同的 monad。我应该为我的ST 代码使用与纯代码不同的东西吗?

【问题讨论】:

  • 可能是sequence? (不过可能有更合适的东西我不知道。)
  • Endo [Error] 在这里可能是最可取的,但实际上“最佳实现”的概念过于宽泛,无法在一个问题中回答。
  • MonadChronicle,也许吧。
  • @AJFarmar 为什么Endo [Error] 是最可取的?我将把我的问题缩小到相对于命令式语言可以获得的效率的“最有效”实现。
  • @DanielWagner 乍一看MonadChronicle 抽象了一个半群。我感兴趣的是 Semigroup 的哪个实例对这项任务最有效,或者除了 writer-esque monad 之外的策略是否最好。我对MonadChronicle 的解释错了吗?

标签: haskell monads state-monad


【解决方案1】:

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

我的一些代码在 ST monad 中,而我的一些代码是纯代码。对于这些不同的用例,我可以使用不同的 monad。我应该为我的ST 代码使用与纯代码不同的东西吗?

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

【讨论】:

  • 我的纯代码已经可以应用了,抱歉没有说清楚。
猜你喜欢
  • 1970-01-01
  • 2011-06-28
  • 2011-07-01
  • 1970-01-01
  • 2018-06-01
  • 2016-05-20
  • 2015-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多