Search code examples
parsinghaskellattoparsec

Parsing CSV header into list of parsers


I want to parse first line of CSV file and to get list of parsers as a result, and fail miserably.

After some simplifications I got code I think should work, but it does not, and I don't understand why.

Here it is:

{-# LANGUAGE OverloadedStrings #-}
import Data.Text
import Data.Attoparsec.Text
import Control.Applicative

doTestSep :: [String] -> Parser [String]
doTestSep t = do
      (endOfLine >> return t)
  <|> (char ';'  *> doTestParse t)

doTestParse :: [String] -> Parser [String]
doTestParse t = do
      (string "<FIELD1>" *> doTestSep ("field1" : t))
  <|> (string "<FIELD2>" *> doTestSep ("field2" : t))

test = parseOnly (doTestParse []) "<FIELD1>"

I call test, expecting to get something like

> Right ["field1"]

but instead I get

> Left "Failed reading: takeWith"

What am I doing wrong?


Solution

  • A problem is wrong input: my title line will definitely have \n or \r\n, which will be catched by endOfLine, and my example input did not have \n in it.

    Working version is

    test = parseOnly (doTestParse []) "<FIELD1>\n"