Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no `MonadTransControl` instance for `ContT`

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?

like image 889
Luka Horvat Avatar asked Oct 30 '22 16:10

Luka Horvat


1 Answers

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.

like image 66
Zemyla Avatar answered Nov 15 '22 08:11

Zemyla