I have a simple continuation type (similar to the 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
I'm then looking to create two interleaved threads of these suspended continuations, all of which to be executed using the same continuing function:
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
I'm now trying to create two threads of suspended operations, which I can then pass to interleave
then into runThread
with a continuation operation to be applied to all suspended operations:
createSuspendedOperations :: Int -> PoorMans (C Maybe) Int
createSuspendedOperations i = atomic $ toBeContinued 12
Error:
No instance for (Monad (C Maybe))
arising from a use of ‘atomic’
I understand that I must make C
an instance of Monad
as atomic
is bound by Monad m =>
:
instance Monad m => Monad (C m) where
However here I am stuck as to how to define the behaviors of >>=
and return
for C m a
?