this 中给出的交错函数让我有点困惑指导。
我有以下数据类型:
data M m r = Atomic (m (M m r)) | Done r
我创建了一个提升函数来获取 m a
, 插入 a
里面Done
, 然后重新插入 Done a
回m ()
.这形成了 Atomic
结构:
atm :: Monad m => m a -> M m a
atm m = Atomic $ liftM Done m
我做了 M m
Monad
的实例类(根据数据构造函数匹配模式):
instance (Monad m) => Monad (M m) where
return = Done
(Atomic m) >>= f = Atomic liftM (>>= f) m
(Done r) >>= f = f v
有一个简单的实现函数可以访问 Atomic wrapper
中的嵌套值:
runThread :: Monad m => M m a -> m a
runThread (Atomic m) = m >>= runThread --Extract m and recursively pass to runThread
runThread (Done r) = return r --Return Done
然后,就有了下面的交错函数:
interleave :: Monad m => M m r -> M m r -> M m r
interleave (Atomic m1) (Atomic m2) = do
next1 <- atm m1 --?
next2 <- atm m2 --?
interleave next1 next2
interleave (Done _) t2 = interleave t2
interleave t1 (Done _) = interleave t1
我的困惑点在 next1 <- atm m1
和 next2 <- atm m2
.
据我了解,这一切所做的就是取 m1
来自 (Atomic m1)
包装器并将其重新插入到 Atomic
中包装?这个操作是如何交错的?
我是不是漏掉了一些基本的东西?代码工作正常,所以我确定这是由于我的困惑。
其余代码:
threadOne :: M IO ()
threadOne = do
atm $ print 1
threadTwo :: M IO ()
threadTwo = do
atm $ print 2
main = do
runThread (interleave threadOne threadTwo)
最佳答案
你说对了一部分。代码
next1 <- atm m1
采取第一个线程开始的原子操作并将其插入到合并/交错线程中。调用 atm
返回的是第一个线程的延续 next1
。
但接下来,我们将从第二个线程采取行动,通过说
next2 <- atm m2
因此合并后的线程最终会执行第一个线程的一个 Action ,然后是第二个线程的一个 Action 。因此“交织”。然后我们通过递归调用 interleave
来继续这两个延续
interleave next1 next2
关于multithreading - 基本线程,交错线程混淆?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42551496/