I have no idea how I'd implement it and I'm assuming that there might not be a way to do it. Is there a proof or a convincing argument that it can't be done?
What makes ContT special?
The only thing you can, in general, get out of a ContT r m is a value of type m r. The type signature of Run (ContT r) would be
Run (ContT r) = forall n b. Monad n => ContT r n b -> n (StT (ContT r) b)
which is equivalent to
forall n b. ((b -> n r) -> n r) -> n (StT (ContT r) b)
The only possible type for StT (ContT r) b is r, but even then, there is no possible defined function of type b -> n r to pass to the ContT. And since liftWith is given a function that requires a value of type Run (ContT r), it can't be implemented.
restoreT makes it even worse, because any value that could possibly be extracted from a general ContT r m a can't be turned back into a ContT r m a. So you lose both coming and going.
Incidentally, this is also the reason you can't make ContT a MonadFix. You can't turn an arbitrary a into an arbitrary r, and vice versa.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With