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 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe