gpt4 book ai didi

haskell - Haskell 中的 IORef

转载 作者:行者123 更新时间:2023-12-01 22:28:10 25 4
gpt4 key购买 nike

我想知道 是否有合法用途IORef 在 haskell ?更具体地说,如果有人可以解决以下问题或指向适当的地方以了解更多信息,我将不胜感激:

  • 使用 IORef 是否被认为是一种糟糕的 Haskell 实践?如果是,为什么?更具体地说,它比 IO monad 好还是坏?
  • 如果有人希望向程序添加状态,那么 state monad 不是更好(更纯)的方式来做到这一点。如果一个人感觉更有必要,他难道不能仍然使用 STM 和 MVar,并且仍然过得更好吗?
  • 是否有使用 IORefs 而不是 STM、MVar 或纯 IO 可以轻松处理的编程场景?

  • 我正在阅读一篇使用 IORef 作为代码片段的论文,由于我对 IORef 的负面看法,这对我来说很难阅读。与其沉迷于我的无知,我认为向我的 Haskellers 同事寻求帮助可能是一个更好的主意。

    最佳答案

    首先,我认为对于论文中的代码片段,使用 IORef是完全明智的,特别是如果这篇论文不是关于可变引用或并发的最佳实践。 IORef易于理解,具有直接的语法和语义(尤其是在非并发环境中),如果您希望读者专注于示例的其他方面而不是 IORef,这是一个自然的选择。 s。不幸的是,作者的方法对您适得其反——请忽略 IORef s 并注意论文的其余部分在说什么。

    (如果这篇论文是关于可变引用或并发的最佳实践,那么它可能是在更好的替代方案可用之前编写的。)

    无论如何,对于您更大的问题,主要反对使用 IORef将是:

  • 与将可变状态引入程序的任何其他机制一样,它使您的代码更难以推理、维护、测试等——函数式编程支持者所说的所有常见事情都让 FP 比突变密集型具有“优势”命令式算法。
  • 它只是一个围绕专门 STRef RealWorld 的新型包装器,以及它添加的唯一内容 STRef是一些原子操作。在非并发代码中,没有充分的理由不使用 STRef s ST s 中的值monad,因为它们更灵活——你可以使用 runST 在纯代码中运行它们或者,如果需要,在 IO monad 中使用 stToIO .
  • 在并发代码中,有更强大的抽象,比如 MVarSTMIORef 更容易使用s。

  • 因此,在一定程度上可变状态是“坏的”,并且——如果你真的需要它——根据你是否需要并发性,有更好的替代方案可用,没有太多值得推荐的 IORef .

    另一方面,如果您已经在 IO 中处理一些非并发代码monad,因为您需要执行实际的 IO 操作,并且您确实需要一些不容易与 IO 分离的普遍可变状态,然后使用 IORef s 似乎是合法的。

    关于您更具体的问题:
  • 我想可以肯定地说使用 IORefweaker tool would do the job 被认为是“不好的做法” .那个较弱的工具可能是 STRef s ,或者更好的是 State monad 或更好的重写的高阶算法,根本不需要任何状态。因为 IORef将 IO 与可变引用相结合,这是一种势在必行的大锤,可能会导致最单调的 Haskell 代码,因此最好避免使用,除非它“显然”是特定问题的正确解决方案。
  • State monad 通常是向程序添加状态的首选惯用方式,但它通过在计算中处理一系列不可变状态值来提供可变状态的“幻觉”,并非所有算法都可以通过这种方式有效实现。如果需要真正的可变状态,则 STRef通常是非并发环境中的自然选择。请注意,您可能不会使用 MVarSTM在非并发设置中——在这种情况下没有理由使用它们,它们会迫使你进入 IO monad,即使你不需要它。
  • 是的,有些编程场景是 IORefSTRef优于 State , STM , MVar ,或纯 IO (见下文)。 IORef的场景很少显然优于 STRef ,但是 - 如上所述 - 如果您已经在 IO 中monad 并且需要与 IO 操作纠缠在一起的真正可变状态,然后 IORef可能比STRef更有优势在稍微干净的语法方面。

  • 以下情况的一些示例 IORefSTRef是一个好方法:
  • Data.Uniquebase包使用 IORef作为生成唯一对象的全局计数器。
  • base库,文件句柄内部广泛使用 IORef s 用于将缓冲区附加到句柄。这是“已经处于 IO monad 中,IO 操作纠缠不清”的一个很好的例子。
  • 许多向量算法使用可变向量最有效地实现(例如,甚至像计算数据块中的字节频率一样简单)。如果您使用来自 vector 的可变向量包,那么从技术上讲,您使用的是可变字节数组而不是 STRefIORef ,但它在道德上仍然是等价的。
  • equivalence包用途STRef s 用于联合连接算法的有效实现。
  • 作为一个有点不切实际的例子,如果你正在为命令式语言实现一个解释器,那么使用 IORefSTRef可变变量的值通常是最有效的。
  • 关于haskell - Haskell 中的 IORef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52467957/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com