On 7/14/07, Stefan O'Rear <stefanor@cox.net> wrote:
On Sat, Jul 14, 2007 at 11:26:56PM -0400, David LaPalomento wrote:
> I've been playing with the parsers decribed in "Monadic Parser Combinators"
> ( http://www.cs.nott.ac.uk/~gmh/bib.html#monparsing) and I've gotten
> stumped.  I'm trying to get comfortable working monadically, so please
> excuse my ignorance.  Here's the relevant portions of my code:

You don't need to excuse yourself.  If you *ever* feel as though you
might regret a question, we have failed.  The point of this list is for
newbies to ask questions and learn!
>
[reordered]
> -- word parses everything as []
> word :: Parser String
> word = mzero `mplus` do
>  x <- letter;
>  xs <- word;
>  return (x:xs)
>
> As I noted in the code, no matter what inputs I give it,
>> parse word "blah blah"
> always returns [].  Any ideas where where my misunderstanding is?

Your base case is subtly wrong - it should be return [], not mzero.
Mzero always fails - mzero `mplus` x = x, by one of the MonadPlus laws.

Ah!  So here's another quick question: if mzero is the identity element, why isn't it part of the Monad class?  Correct me if I'm wrong but aren't Monads (in the mathematical sense) required an identity element by definition? 

> sat :: (Char -> Bool) -> Parser Char
> sat p = Parser (\inp -> [ (v, out) | (v, out) <- parse item inp, p v])
>
> lower :: Parser Char
> lower = Parser (\inp -> parse (sat (\x -> 'a' <= x && x <= 'z')) inp)
>
> upper :: Parser Char
> upper = Parser (\inp -> parse (sat (\x -> 'A' <= x && x <= 'Z')) inp)

These definitions aren't in the best style; while they are correct, I
would prefer to write them as:

sat :: (Char -> Bool) -> Parser Char
sat p = do { ch <- item ; guard (p ch) ; return ch }

lower :: Parser Char
lower = sat isLower

upper :: Parser Char
upper = sat isUpper

Thanks for the style tips.  Your definition is much clearer (as well as more succinct).

Stefan

Thanks again!
David