Home > Net >  Taking a parser in argument and try to apply it zero or more times
Taking a parser in argument and try to apply it zero or more times

Time:10-05

I am currently writing a basic parser. A parser for type a takes a string in argument and returns either nothing, or an object of type a and the rest of the string.

Here is a simple type satisfying all these features:

type Parser a = String -> Maybe (a, String)

For example, I wrote a function that takes a Char as argument and returns a Parser Char :

parseChar :: Char -> Parser Char
parseChar _ [] = Nothing
parseChar c (x:xs)
    | c == x = Just (x, xs)
    | otherwise = Nothing

I would like to write a function which takes a parser in argument and tries to apply it zero or more times, returning a list of the parsed elements :

parse :: Parser a -> Parser [a]

Usage example:

> parse (parseChar ' ') "    foobar"
Just ("    ", "foobar")

I tried to write a recursive function but I can't save the parsed elements in a list.

How can I apply the parsing several times and save the result in a list ?

CodePudding user response:

I tried to write a recursive function but I can't save the parsed elements in a list.

You don't need to "save" anything. You can use pattern matching. Here's a hint. Try to reason about what should happen in each case below. The middle case is a bit subtle, don't worry if you get that wrong at first. Note how s and s' are used below.

parse :: Parser a -> Parser [a]
parse p s = case p s of
   Nothing     -> ...    -- first p failed
   Just (x,s') -> case parse p s' of
      Nothing       -> ...   -- subtle case, might not be relevant after all
      Just (xs,s'') -> ...   -- merge the results

Another hint: note that according to your description parse p should never fail, since it can always return the empty list.

  • Related