
Ryan Ingram wrote:
To take this a step further, there is the DSL:
get :: m S put :: S -> m ()
and the concrete implementation
m = State S
Of course, there are other monads which implement this DSL as well:
m = StateT S IO
m = Prompt StatePrompt with data StatePrompt a where Get :: StatePrompt S Put :: S -> StatePrompt ()
Elaborating on that, the DSL consists of two specific functions get, put and two general function (>>=), return Every combination of those is a program in the DSL. Example programs: get >>= put get >>= \x -> return (x,x) put 1 >>= \() -> get >>= \x -> return (2*x) This is the *syntactic* part of the DSL. Of course, we also need *semantics*, and those are given by an interpreter function. Examples: interpret :: m a -> (S -> a) interpret :: m a -> (S -> (a,S)) interpret :: m a -> StateT S IO a When the state monad is implemented as m a = S -> (a,S) this function is just the identity interpret :: (S -> (a,S)) -> (S -> (a,S)) interpret = id but as the MonadPrompt or operational packages show, this does not need to be the case; it is, in fact, beneficial to use a generic representation for the syntax and make the interpret function do all the work. Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com