Search code examples
parsinghaskellparsec

Haskell and Parsec: Parsing two separated lists of numbers


I've been experimenting with Parsec for the first time in my life and I found a task that turned out surprisingly difficult.

I want to parse two lists of numbers separated by | character. Here's an example:

Data 1: 43 76 123 98 32 | 32 88 43 123 43

Here's the code I've come up so far

data Data = Data Int [Int] [Int]
    deriving Show

toInt :: String -> Int
toInt = read

parseRow :: Parser Data
parseRow = do
    _ <- Parsec.string "Data"
    _ <- Parsec.spaces
    cid <- toInt <$> many1 Parsec.digit
    firstList <- map toInt <$> between (Parsec.string ": ") (Parsec.char '|') (many1 (many1 Parsec.digit <* Parsec.space))
    secondList <- map toInt <$> sepBy1 (many1 Parsec.digit) (Parsec.char ' ')
    return $ Data cid firstList secondList

It gets confused while parsing firstList. I guess I messed up parsing the spaces separating the numbers, but can't see an obvious mistake.

Going forward, what's the most beginner-friendly introduction to Parsec? I found a few tutorials, but happy to hear recommendations.


Solution

  • Replace Parsec.char '|' with Parsec.string "| " in firstList. Otherwise, secondList has to deal with an extra space at the beginning of the input that it doesn't expect.