gpt4 book ai didi

haskell - 带有 stateT 的 ForkIO

转载 作者:行者123 更新时间:2023-12-03 10:18:49 28 4
gpt4 key购买 nike

我们如何让用户传递一个 eventHandler,它使用 stateMonad 但在单独的线程中调用?比如下面的例子中,应该如何调用forkIO,以便eventHandler可以调用操作呢?我是 Haskell 的新手,如果这是向用户公开的错误 api,请纠正我?

data MyTypeResult a = MyTypeValue a
data MyTypeState = MyTypeState {_counter :: Int}

newtype MyType a = MyType {
unMyType :: StateT MyTypeState IO (MyTypeResult a)
}

instance Monad MyType where
(>>=) = myTypeBind
return = myTypeReturn
fail = myTypeFail

myTypeBind = undefined
myTypeReturn = undefined
myTypeFail = undefined

type Event = String
type Handler = Event -> MyType ()

doSomethingAwesome :: MyType Event
doSomethingAwesome = undefined

operate :: String -> MyType ()
operate = undefined

start :: Handler -> MyType ()
start h = do
event <- doSomethingAwesome
--forkIO $ h event -- The line that is troubling
return ()

testHandler :: Event -> MyType()
testHandler _ = operate "abcd"

myMain = start testHandler

最佳答案

你不能让 State 计算在共享相同状态的多个线程中运行,因为在幕后,State monad 只不过是一个通过的函数调用链链中下一个函数的状态值。

对于多线程代码,您可以将 StateT s IO 替换为 ReaderT (IORef s) IO 并使用

forkIO $ runReaderT (h event) stateVar

fork 新线程(其中 stateVar 是一个包含共享状态的 IORef)。

ReaderT 堆栈中,您使用

读取当前共享状态
stateVar <- ask
s <- lift $ readIORef stateVar

并更新它

stateVar <- ask
lift $ atomicModifyIORef stateVar f

其中f是一个纯函数,它获取当前状态并返回修改后的状态加上一个辅助结果。

如果你需要更多花哨的东西(例如使用单子(monad)函数修改状态),那么你应该使用 MVarTVar 而不是 IORef.

关于haskell - 带有 stateT 的 ForkIO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18233902/

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