[Haskell-beginners] Consuming Rule Based Parsing

Karl Voelker ktvoelker at gmail.com
Sat Nov 17 05:03:51 CET 2012


On Fri, Nov 16, 2012 at 7:53 PM, Christopher Howard <
christopher.howard at frigidcode.com> wrote:

> data Noun = Noun String
> data Verb = Verb String
> data Sentence = Sentence Noun Verb
>
> nounParser :: Parser Noun
> nounParser = ...
>
> verbParser :: Parser Verb
> verbParser = ...
>

This is a good example to start with.


> sentenceParser :: Parser Sentence
> sentenceParser = nounParser <+> verbParser
>
> (<+>) :: ?
> (<+>) f g = ?


Based on the types of nounParser, verbParser, and sentenceParser, we can
infer that:

(<+>) :: Parser Noun -> Parser Verb -> Parser Sentence

But I suspect you were hoping that <+> would be more general-purpose. The
combinator you want is the one I previously called "andThen":

andThen :: Parser a -> (a -> Parser b) -> Parser b

Which you could use like this:

sentenceParser = nounParser `andThen` (\noun -> verbParser `andThen` (\verb
-> succeedWith (Sentence noun verb)))

Notice that the difference between your <+> and my andThen is that andThen
requires the caller to provide the function that combines the two inputs
into one output. This is what keeps it general.


Now for a slight digression:

If this looks frustratingly verbose, that's because it is. But if you make
Parser into a monad (where return is succeedWith and >>= is andThen), you
can use the syntactic sugar that is "do notation":

sentenceParser = do
  noun <- nounParser
  verb <- verbParser
  return (Sentence noun verb)

-Karl
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20121116/72ecfd3e/attachment.htm>


More information about the Beginners mailing list