CPS协程:为什么这个例子需要exhaust?

CPS Coroutines: Why does this example require exhaust?

我想从 wikibooks/HaskellCPS 章节中找出 the coroutines example,但我不能理解为什么 runCoroutineT 函数最后需要 . (<* exhaust),如果我将函数从

更改为
runCoroutineT = flip evalStateT [] . flip runContT return . runCoroutineT' . (<* exhaust)

runCoroutineT = flip evalStateT [] . flip runContT return . runCoroutineT'

这个例子好像keep working(看第56行) 如果有错误,谁能解释一下?

在我看来它不可行。您链接到的示例程序以

结尾
example = runCoroutineT $ do
    fork $ replicateM_ 3 (printOne 3)
    fork $ replicateM_ 4 (printOne 4)
    replicateM_ 2 (printOne 2)

但是当运行时,并不是所有的4都打印出来了:

3
4
3
2
4
3
2
4

应该是四个!

exhaust 的要点是结束所有等待 运行 的线程,如果 运行 没有它,一些线程可能无法完成。