
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