You can construct a monad very simply with prompt, by putting all of its effects as terms in a GADT, like the following example:
data PromptState s a where
Put :: s -> PromptState s ()
Get :: PromptState s s
You then use prompt to access effects:
postIncrement :: MonadPrompt (PromptState Int) m => m Int
postIncrement =
do x <- prompt Get
prompt (Put (x+1))
return x
The advantage of Prompt over implementing effects directly:
Prompt is pure; it is only through the observation function runPromptC that you can cause effects.
You don't have to worry about the monad laws; they are correct by construction and you cannot break them.
You can implement several observation functions for the same type. See, for example, http://paste.lisp.org/display/53766 where a guessing game is implemented with an IO observation function for the user, and an AI observation function that plays the game automatically.
In these ways Prompt is similar to Unimo, but bind and return are inlined into the computation, whereas in Unimo they are handled as a term calculus. See http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=89
Methods
prompt :: p a -> m a
Instances4MonadPrompt
MonadPrompt p (Prompt p)Defined in MonadPrompt-1.0.0.5 · Control.Monad.PromptMonadPrompt p (PromptT p m)Defined in MonadPrompt-1.0.0.5 · Control.Monad.PromptMonadPrompt (p (RecPrompt p)) (RecPrompt p)Defined in MonadPrompt-1.0.0.5 · Control.Monad.PromptMonadPrompt (p (RecPromptT p m)) (RecPromptT p m)Defined in MonadPrompt-1.0.0.5 · Control.Monad.Prompt