2017-03-02 103 views
3

我對this指南中給出的交錯函數有些困惑。基本線程,交錯線程混淆?

,我有以下數據類型:

data M m r = Atomic (m (M m r)) | Done r 

我創建了一個升降功能採取m a,裏面插入的Donea,然後重新插入Done a回到m()。這形成了Atomic結構:

atm :: Monad m => m a -> M m a 
atm m = Atomic $ liftM Done m 

我做M mMonad類的一個實例(其中模式匹配基於數據的構造函數):

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 m1next2 <- atm m2

據我瞭解,這一切正在做的是從(Atomic m1)包裝採取m1並重新插入它放回一個Atomic包裝?這個操作是如何交錯的?

我在這裏錯過了一些基本的東西嗎?代碼工作正常,所以我相信這是由於我的困惑。

的其餘代碼:

threadOne :: M IO() 
threadOne = do 
    atm $ print 1 

threadTwo :: M IO() 
threadTwo = do 
    atm $ print 2 

main = do 
    runThread (interleave threadOne threadTwo) 

回答

2

你是正確的部分。代碼

next1 <- atm m1 

取第一個線程開始的原子動作並將其插入到合併/交錯線程中。呼叫atm返回的是第一個線程的延續next1

但是接下來,我們正在從第二個線程的動作,說

next2 <- atm m2 

所以合併後的線程結束執行來自第一線的動作,然後從第二個線程之一。因此「交錯」。然後,我們繼續通過interleave遞歸地在兩個連續處通過

interleave next1 next2