I can not do to expand the question. But here is a precedent: suppose you have two monad transformers, t and s , which are converted to the same monad m :
master :: (MonadTrans t, Monad m) => tmab slave :: (MonadTrans t, Monad m) => smab
And I want to make master and slave so that they can communicate with each other when m primitives were raised by t and s . Signature may be:
bound :: (MonadTrans t, MonadTrans s, Monad m, Monoid a) => tmab -> smab -> (...) But what is the type of (...) ?
Use case in a note with sugar:
master :: Monoid a => a -> tmab master a = do a <- lift . send $ (a,False) -- * here master is passing function param to slave ... -- * do some logic with a b <- lift . send $ (mempty,True) -- * master terminates slave, and get back result slave :: Monoid a => (a -> b) -> smab slave g = do (a,end) <- lift receive case end of True -> get >>= \b -> exit b _ -> (modify (++[ga])) >> slave g
Update: send and receive are primitives of type m .
I apologize if this example looks far-fetched or too similar to coroutines, the spirit of the question really has nothing to do with it, so please ignore all the similarities. But the main thing is that the monads t and s could not be reasonably composed with each other before, but after both wrapped some basic monad m , they can now be composed and executed as one function. As for the type of function compiled, I'm really not sure, so some direction is appreciated. Now, if this abstraction already exists, and I just donβt know about it, then it would be better.