考虑一下一些monad变压器堆栈
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
...
newtype J = J { runJ :: ErrorT Foo (StateT Bar IO) a } deriving (Applicative, Functor, etc)
以及
J
中的一些功能:peekNextQuux :: J Quux
peekNextQuux = ...
withJ :: J a -> IO (Either Foo a)
withJ = ...
然后我发现自己在
J
上下文中。我会写f = withJ $ peekNextQuux >>= liftIO . print
现在我想在
J
上下文中的单独线程中窥视并打印队列g = withJ . liftIO . forkIO . forever $ peekNextQuux >>= liftIO . print
这显然是行不通的。我想有办法解决这个简单的问题,只是想不通。
最佳答案
您希望它如何运作?单独的线程必须有权访问某些状态和错误处理,因为J
包装了StateT
和ErrorT
。线程应该如何访问它?在新线程中更新状态时,是否也应该在旧线程中更改状态?当新线程引发异常时,旧线程应该停止吗?
它不起作用,因为StateT
和ErrorT
是纯monad转换器,所以我描述的行为无法实现。您必须将状态显式传递给新线程并在其中运行新状态monad才能使其工作:
g = withJ . ... $ do
state <- get
liftIO . forkIO $ do
flip execStateT state . forever $ peekNextQuux >>= liftIO . print