gpt4 book ai didi

haskell - 你如何在 Haskell 中构建一个有状态的模块?

转载 作者:行者123 更新时间:2023-12-04 03:34:33 24 4
gpt4 key购买 nike

我正在寻找一个通用模块,允许 Haskell 程序与 Cassandra 交互。模块需要维护自己的状态。例如,它将有一个连接池和一个在保存新记录时要调用的回调列表。我应该如何构造代码以便该模块可以保持其状态?以下是我一直在考虑的一些方法。我在正确的轨道上吗? (我是 Haskell 的新手,仍在学习功能思考的最佳方法。)

选项1:

该模块在 (StateT s IO) monad 中运行,其中 s 是使用 Cassandra 模块的整个程序的全局状态。当然,由于 Cassandra 模块可以被多个程序使用,所以 s 中的内容的详细信息应该对 Cassandra 模块是不可见的。该模块必须导出一个类型类,使其能够从 s 中提取 CassandraState 并将新的 CassandraState 推回 s 中。然后,任何使用该模块的程序都必须使其主状态成为该类型类的成员。

选项 2:

该模块在 (StateT CassandraState IO) monad 中运行。每次有人在模块中调用一个 Action 时,他们都必须从他们隐藏的任何地方提取 CassandraState,使用 runState 调用该 Action ,然后获取结果状态并再次将其隐藏(无论在哪里)。

选项 3:

根本不要将 Cassandra 模块的函数放在 StateT monad 中。相反,让调用者在需要时显式传递 CassandraState。选项 2 的问题是,并非模块中的所有函数都会修改状态。例如,获取连接将修改状态,并要求调用者隐藏结果状态。但是,保存新记录需要读取状态(以获取回调),但不需要更改状态。选项 2 不会给调用者任何暗示 connect 会改变状态,而 create 不会。

但是,如果我不再使用 StateT monad,而只使用将状态作为参数并返回简单值或简单值和新状态的元组的函数,那么当需要保存状态时,调用者会很明显. (在我的模块中,我将传入状态并将它们构建到一个 (StateT CassandraState IO) monad 中,但是这个细节将对调用者隐藏。所以,对于调用者来说,接口(interface)是非常明确的,但在幕后,它只是选项 2。)

选项 4:

还有什么?

在构建可重用模块时,这个问题必须经常出现。是否有某种标准的方法来解决它?

(顺便说一句,如果有人知道从 Haskell 与 Cassandra 交互比使用 Thrift 更好的方法,请告诉我!也许我根本不需要写这个。:-)

最佳答案

类似于 HDBC 模型的东西是有一个明确的 CassandraConnection数据类型。它内部有一个带有一些可变状态的 MVar。由于我想你的所有操作都在 IO 中,所以他们可以将 CassandraConnection 作为这些操作的参数。然后,用户可以将该连接打包到一个状态或阅读器 monad 中,或者显式地将其线程化,或者做任何他们想做的事情。

在内部,你可以使用或不使用 monad——这真的是你的决定。然而,我更喜欢那些尽可能不强制用户进入任何特定单子(monad)的 API,除非真的有必要。

所以这是选项 3 的一种版本。但是用户不应该真正关心他们是否正在更改连接状态——在那个级别上,您可以真正对他们隐藏细节。

关于haskell - 你如何在 Haskell 中构建一个有状态的模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4785379/

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