gpt4 book ai didi

haskell - 如何修改状态单子(monad)?

转载 作者:行者123 更新时间:2023-12-02 16:16:33 29 4
gpt4 key购买 nike

我使用 State Monad Transformer 来管理这样的全局状态

data State = State ...
StateT State IO ()

我使用 amqp 来消费来自 RabbitMQ 的消息。状态将根据收到的消息进行修改。该函数的类型类似于

consumeMsgs :: Channel 
-> Text
-> Ack
-> ((Message, Envelope) -> IO ()) -- ^ the callback function
-> IO ConsumerTag

现在我们可以忽略其他参数,但第三个参数是我将提供的回调函数以及修改发生的位置。

因为它主要是IO Monad,所以我使用这个函数如下

consumeMsgs chan queue Rmq.Ack (flip evalStateT ssss . rmqCallback)

这里的ssss是我放入的状态,我发现在我的回调函数rmqCallback的过程中,状态可以被正确修改。但是,每次发生下一个回调时,全局状态都与调用 ConsumerMsgs 之前相同或等于 ssss

我知道 State Monad 只是一个需要初始状态来放入并在整个过程中维护状态的过程,但与 Monad 之外的状态无关(我错过了什么吗?),所以我依靠 MVar 来保持并修改状态,这样就可以了。我想知道还有其他方法可以处理这个问题,也许是另一个 Monad?

最佳答案

看起来你可以使用 Network.AMQP.Lifted.consumeMsgsStateT s IOMonadBaseControl IO m 的一个实例,这样你就可以运行整个 consumeMsgs内单 runStateT

是的,StateT monad 转换器基本上是纯代码的一个很好的表示法,因此如果您的 API 只接受 IO 回调,您别无选择,只能使用“真实”状态,如 MVar 或 IORef 等。

PS:如 other answer表明,状态更改在 Network.AMQP.Lifted.consumeMsgs 中完成的回调不会传播到后续回调运行或结果状态。我无法理解实现,但我尝试了 liftBaseWith一点点,看起来真的是这样。

关于haskell - 如何修改状态单子(monad)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50166215/

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