Monads can do many amazing, crazy things. They can create variables which hold a superposition of values. They can allow you to access data from the future before you compute it. They can allow you to write destructive updates, but not really. And then the continuation monad allows you to break people’s minds! Ususally your own. 😉
But here’s a challenge: Can you make a monad which can be paused?
data Pause s x instance Monad (Pause s) mutate :: (s -> s) -> Pause s () yield :: Pause s () step :: s -> Pause s () -> (s, Maybe (Pause s ()))
The Pause monad is a kind of state monad (hence mutate, with the obvious semantics). Normally a monad like this has some sort of “run” function, which runs the computation and hands you back the final state. But Pause is different: It provides a step function, which runs the computation until it calls the magical yield function. Here the computation is paused, returning to the caller enough information to resume the computation later.
For extra awesomness: Allow the caller to modify the state between step calls. (The type signatures above ought to allow this, for example.)
Use case: It’s often easy to write code that does something complex, but a total PITA to transform it to also output the intermediate states in its operation. If you want the user to be able to change something mid-way through execution, things get complex really fast.
Implementation ideas:
-
Obviously it can be done with threads, locks and
IO. But can we do better? 😉 -
Something insane with a continuation monad?
-
Maybe some kind of writer monad, where
yieldjust logs the current state, and then we can “pretend” tostepit by iterating over the states in the log. (Obviously this precludes altering the state between steps, since we’re not really “pausing” anything now.)
Sure; you just let any computation either finish with a result, or suspend itself, giving an action to be used on resume, along with the state at the time:
The
Monadinstance just sequences things in the normal way, passing the final result to thekcontinuation, or adding the rest of the computation to be done on suspension.