如何在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
有关,但我不知道它们是什么。ACoroutineT
只是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
这样做,但它可能无法这样做,因为它是一个递归类型定义