Monad transformer for multi-prompt delimited control

It implements the superset of the interface described in

- "
*A Monadic Framework for Delimited Continuations*", R. Kent Dybvig, Simon Peyton Jones, and Amr Sabry JFP, v17, N6, pp. 687--730, 2007. http://www.cs.indiana.edu/cgi-bin/techreports/TRNNN.cgi?trnum=TR615

The first main difference is the use of generalized prompts, which do not have to be created with new_prompt and therefore can be defined at top level. That removes one of the main practical drawbacks of Dybvig et al implementations: the necessity to carry around the prompts throughout all the code.

The delimited continuation monad is parameterized by the flavor of generalized prompts. The end of this code defines several flavors; the library users may define their own. User-defined flavors are especially useful when user's code uses a small closed set of answer-types. Flavors PP and PD below are more general, assuming the set of possible answer-types is open and Typeable. If the user wishes to create several distinct prompts with the same answer-types, the user should use the flavor of prompts accepting an integral prompt identifier, such as PD. Prompts of the flavor PD correspond to the prompts in Dybvig, Peyton Jones, Sabry framework. If the user wishes to generate unique prompts, the user should arrange himself for the generation of unique integers (using a state monad, for example). On the other hand, the user can differentiate answer-types using `newtype.' The latter can only produce the set of distinct prompts that is fixed at run-time. Sometimes that is sufficient. There is not need to create a gensym monad then.

The second feature of our implementation is the use of the bubble-up semantics: See page 57 of http://okmij.org/ftp/gengo/CAG-talk.pdf This present code implements, for the first time, the delimited continuation monad CC *without* the use of the continuation monad. This code implements CC in direct-style, so to speak. Instead of continuations, we rely on exceptions. Our code has a lot in common with the Error monad. In fact, our code implements an Error monad for resumable exceptions.

- data CC p m a
- type SubCont p m a b = CC p m a -> CC p m b
- type CCT p m a w = SubCont p m a w -> CC p m w
- type Prompt p m w = (forall x. CCT p m x w -> p m x, forall x. p m x -> Maybe (CCT p m x w))
- pushPrompt :: Monad m => Prompt p m w -> CC p m w -> CC p m w
- takeSubCont :: Monad m => Prompt p m w -> CCT p m x w -> CC p m x
- pushSubCont :: Monad m => SubCont p m a b -> CC p m a -> CC p m b
- runCC :: Monad m => CC (p :: (* -> *) -> * -> *) m a -> m a
- abortP :: Monad m => Prompt p m w -> CC p m w -> CC p m any
- shiftP :: Monad m => Prompt p m w -> ((a -> CC p m w) -> CC p m w) -> CC p m a
- shift0P :: Monad m => Prompt p m w -> ((a -> CC p m w) -> CC p m w) -> CC p m a
- controlP :: Monad m => Prompt p m w -> ((a -> CC p m w) -> CC p m w) -> CC p m a
- data PS w m x
- ps :: Prompt (PS w) m w
- data P2 w1 w2 m x
- p2L :: Prompt (P2 w1 w2) m w1
- p2R :: Prompt (P2 w1 w2) m w2
- data PP m x
- pp :: Typeable w => Prompt PP m w
- data PM c m x
- pm :: Typeable w => Prompt (PM c) m w
- data PD m x
- newPrompt :: Typeable w => Int -> Prompt PD m w
- as_prompt_type :: Prompt p m w -> w -> Prompt p m w

# Types

Delimited-continuation monad transformer It is parameterized by the prompt flavor p

type Prompt p m w = (forall x. CCT p m x w -> p m x, forall x. p m x -> Maybe (CCT p m x w))Source

Generalized prompts for the answer-type w: an injection-projection pair

# Basic delimited control operations

pushSubCont :: Monad m => SubCont p m a b -> CC p m a -> CC p m bSource

Apply the captured continuation

# Useful derived operations

# Pre-defined prompt flavors

The extreme case: prompts for the single answer-type w. The monad (CC PS) then is the monad for regular (single-prompt) delimited continuations

There is only one generalized prompt of the flavor PS for a given answer-type w. It is defined below

Prompts for the closed set of answer-types The following prompt flavor P2, for two answer-types w1 and w2, is given as an example. Typically, a programmer would define their own variant data type with variants for the answer-types that occur in their program.

The same as PP but with the phantom parameter c
The parameter is useful to statically enforce various constrains
(statically pass some information between shift and reset)
The prompt PP is too `dynamic`

: all errors are detected dynamically
See Generator2.hs for an example

Open set of answer types, with an additional distinction (given by integer identifiers) This prompt flavor corresponds to the prompts in the Dybvig, Peyton-Jones, Sabry framework (modulo the Typeable constraint).

as_prompt_type :: Prompt p m w -> w -> Prompt p m wSource

It is often helpful, for clarity of error messages, to specify the answer-type associated with the prompt explicitly (rather than relying on the type inference to figure that out). The following function is useful for that purpose.