Thanks for the hint, I will try to implement the suggested monadic structure. As for the MonadState declaration: If I put instance MonadState PState Parser then ghci complains: Illegal instance declaration for 'MonadState PState Parser' (The instance type must be of form (T a b c) where T is not a synonym, and a,b,c are distict type variables) In the instance declaration for 'MonadState PState Parser' I found out that invoking ghci with "-fglasgow-exts" solves the issue nut I have to admit that I do not really understand what's so special about this instance declaration to make it require the extensions. Harald. Andrew Pimlott <andrew@pimlott.net To: Harald ROTTER <harald.rotter@sagem.com> > cc: haskell@haskell.org Subject: Re: [Haskell] Monadic parser combinators with logging 03.08.2006 02:54 Delivered date: 03.08.2006 02:54 On Wed, Aug 02, 2006 at 10:52:14AM +0200, Harald ROTTER wrote:
newtype Parser a = Parser { runParser :: (PState -> [(a, PState)])}
as the parsing monad with the Parser state "PState" that contains the remaining input after matching and possibly some additional user defined state elements. I want to add logging such that the application of every element parser/parser combinator gets recorded in a string. In the end I want to print out the trace of all encountered parsers for successful and for failed matches.
I tried to use the WriterT transformer to add a writer monad on top of the Parser monad but for failed matches (i.e. runParser gives []) the log is also "lost" since WriterT gives a monad of "m (a,w)".
Excellent observation! The order in which you apply monad transformers matters. "WriterT w Parser" keeps a separate output for each branch of the parser. If you stare at the definition of (>>=) for WriterT, you'll see why this must be so. Or, as you did, you can just look at the type.
What I would look for is "(m a, w)".
Hmm, that looks like (if m is Parser) a parser plus some output. I think you'd rather have an answer plus some output, ie "([(a, PState)], w)". Hint: Consider newtype Parser m a = Parser { runParser :: (PState -> m [(a, PState)])} where m is a Monad.
How can I make the Parser monad given above an instance of MonadState ? (I always get kind errors ...)
Did you switch up the order of parameters or something? I don't get any error using instance MonadState Int Parser where ... Andrew