
Derek Elkins wrote:
What you're actually showing is that these effects can be -embedded- in IO (i.e. that IO already supports them). I noticed you didn't try to make an instance for the Cont monad. Actually, if we added continuations to IO, we'd be set. We wouldn't even need your typeclass.
Yes, precisely. Your use of the term 'embedded' parallels the fact I called the method 'embed'. It's a useful technique because it enables you to give more specific types to your functions: to use StateT IO instead of just using IO and instead of using ad-hoc IORefs yourself you can use the StateT methods and have the IORefs behind the scenes when you need to thread through another monad. Similarly you can give pure types to callbacks (either plain State s, or the parametric forall m. StateT s m) which makes it easier to specify and test them. It even has applications in an untrusted code environment, where it's dangerous to accept callbacks of IO type. Of course, you can't do Cont or List (unless I'm missing something) because they are both capable of duplicating the current continuation, and it's not possible to duplicate the entire IO state (a.k.a. the RealWorld#). Jules