
On 7/14/07, Stefan O'Rear
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