On Fri, Nov 16, 2012 at 7:53 PM, Christopher Howard <christopher.howard@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