【问题标题】:How to implement Coroutine queue in Haskell?Haskell中如何实现协程队列?
【发布时间】:2014-12-30 03:17:23
【问题描述】:

在延续tutorial 的底部附近有一个以

开头的协程实现
-- 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 和putCCs 定义了dequeue 和queue 函数。

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

【问题讨论】:

    标签: haskell coroutine


    【解决方案1】:

    CoroutineT 只是 monad 转换器堆栈 ContT r (StateT [CoroutineT r m ()] m) a 类型的包装器。这实质上意味着它是包装状态类型为[CoroutineT r m ()] 的状态单子的延续单子。 get 和 put 函数是 MonadState 类型类的成员,StateT 实现了它。当您调用lift get 时,它的类型为(MonadTrans t, MonadState m s) => t m s。由于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 类型中。这也与putCCs 非常相似。所有这些都是获取和设置[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
    

    理想情况下,您可以让GeneralizedNewtypeDeriving 执行此操作,但它可能无法执行,因为它是递归类型定义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-30
      • 2014-08-24
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      • 1970-01-01
      • 1970-01-01
      • 2011-03-27
      相关资源
      最近更新 更多