如何在Haskell中实现协同路由队列?

如何在Haskell中实现协同路由队列?,haskell,coroutine,Haskell,Coroutine,在延续的底部,有一个以 -- The CoroutineT monad is just ContT stacked with a StateT containing the suspended coroutines. newtype CoroutineT r m a = CoroutineT {runCoroutineT' :: ContT r (StateT [CoroutineT r m ()] m) a} deriving (Functor,Applicative,Monad,Mo

在延续的底部,有一个以

-- The CoroutineT monad is just ContT stacked with a StateT containing the suspended coroutines.
newtype CoroutineT r m a = CoroutineT {runCoroutineT' :: ContT r (StateT [CoroutineT r m ()] m) a}
    deriving (Functor,Applicative,Monad,MonadCont,MonadIO)

-- Used to manipulate the coroutine queue.
getCCs :: Monad m => CoroutineT r m [CoroutineT r m ()]
getCCs = CoroutineT $ lift get

putCCs :: Monad m => [CoroutineT r m ()] -> CoroutineT r m ()
putCCs = CoroutineT . lift . put
然后还使用
getCCs
putcs
定义了
dequeue
queue
函数


我不明白如何维护协同路由队列。
getCCs
putcs
的类型签名似乎并不表示在调用之间维护的任何类型的“变量”。我怀疑在
getCCs
putcs
的实现中,状态与
get
put
有关,但我不知道它们是什么。

A
CoroutineT
只是monad transformer堆栈
ContT r(StateT[CoroutineT r m()]m)A
类型的包装器。这本质上意味着它是包装状态单子的延续单子,其中状态类型为
[CoroutineT r m()]
get
put
函数是
MonadState
typeclass的成员,由
StateT
实现。调用
lift get
时,它的类型为
(MonadTrans t,MonadState ms)=>tms
。由于
StateT s
MonadState s
的一个实例,而在我们的例子中
s
[CoroutineT r m()]
,我们可以将它们插入

lift get
    :: (MonadTrans t, Monad m)
    => t (StateT [CoroutineT r m ()] m) [CoroutineT r m ()]
由于
ContT r
实现了
MonadTrans
,我们可以在中替换它并获得

lift get
    :: (Monad m)
    => ContT r (StateT [CoroutineT r m ()] m) [CoroutineT r m ()]
现在,如果我们把它包装在
CoroutineT
构造函数中,我们得到

CoroutineT $ lift get
    :: (Monad m)
    => Coroutine r m [CoroutineT r m ()]
这是一个很大的类型争论,只是说
CoroutineT$lift get
正在将
MonadState
get
函数包装到
CoroutineT
类型中。这与
putcs
也非常相似。所有这些操作都是获取并设置
[CoroutineT r m()]
的内部状态,并很好地封装在这个monad中。您可以使用这些定义使
CoroutineT
成为
MonadState[CoroutineT r m]

instance MonadState [CoroutineT r m ()] (CoroutineT r m) where
    get = CoroutineT $ lift get
    put = CoroutineT . lift . put
理想情况下,您可以让
generalizednewtypedering
这样做,但它可能无法这样做,因为它是一个递归类型定义