线程延续混乱?

时间:2017-03-23 17:00:08

标签: haskell concurrency continuations

我有一个简单的延续类型(类似于Free monad):

data C m a = C {runC :: (a -> m a) -> m a}

toBeContinued :: Int -> C Maybe Int
toBeContinued i = C $ \todo -> todo i

continuing :: Int -> Maybe Int
continuing i = Just 100

然后我想创建这些暂停延续的两个交错线程,所有这些线程都使用相同的连续函数执行:

data PoorMans m a = Atomic (m (PoorMans m a)) | Done a

instance Monad m => Monad (PoorMans m) where
  (>>=) (Atomic m) f = Atomic $ (liftM (>>= f) m)
  (>>=) (Done m) f = f m
  return  = Done

atomic :: Monad m => m a -> PoorMans m a
atomic m = Atomic $ liftM Done m

runThread :: Monad m => m a -> PoorMans m a
runThread (Atomic m) = m >>= runThread
runThread (Done m) = return m

interleave :: Monad m => PoorMans m a -> PoorMans m a -> PoorMans m a
interleave (Atomic m1) (Atomic m2) = do
    n1 <- m1
    n2 <- m2
    interleave n1 n2
interleave (Done _) m2 = m2
interleave m1 (Done _) = m1

我现在正在尝试创建两个挂起操作的线程,然后我可以将其传递给interleave然后传递到runThread,并继续操作以应用于所有挂起的操作:

createSuspendedOperations :: Int -> PoorMans (C Maybe) Int
createSuspendedOperations i = atomic $ toBeContinued 12

错误:

 No instance for (Monad (C Maybe))
    arising from a use of ‘atomic’

我知道我必须C Monad atomic的实例,因为Monad m => instance Monad m => Monad (C m) where 约束:

>>=

但是,我对于如何定义returnC m a list : [ { ItemNumber: 1, ItemPhotos: null }, { ItemNumber: 2, ItemPhotos: ["Photo1Url", Photo2Url, Photo3Url...] }, { ItemNumber: 3, ItemPhotos: ["Photo1Url", Photo2Url,...] }, ... ] 的行为感到困惑?

1 个答案:

答案 0 :(得分:1)

这不是monad,因为aC m a的不变参数。 (Here is an FPComplete post about variance.

您可能需要查看"continuation monad" in transformers