Разбор заголовка CSV в список парсеров

Я хочу разобрать первую строку CSV-файла и получить в результате список парсеров и с треском провалиться.

После некоторых упрощений я получил код, который, я думаю, должен работать, но он не работает, и я не понимаю, почему.

Вот:

{-# 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>"

Я звоню test, ожидая получить что-то вроде

> Right ["field1"]

но вместо этого я получаю

> Left "Failed reading: takeWith"

Что я делаю не так?


person Alexander Kusev    schedule 31.08.2014    source источник
comment
В документации для endOfLine говорится: Сопоставьте либо один символ новой строки '\n', либо возврат каретки, за которым следует символ новой строки \r\n.. Однако ваш ввод не содержит ни \n, ни \r\n, так что парсер выйдет из строя.   -  person bennofs    schedule 31.08.2014
comment
@bennofs спасибо, ты прав. Это работает, и мой вопрос — это вопрос слепого.   -  person Alexander Kusev    schedule 31.08.2014
comment
Обратите внимание, что существует несколько хороших библиотек CSV для Haskell, в зависимости от ваших вкусов, и в Real World Haskell есть раздел, посвященный использованию parsec для написания парсера CSV, к которому вы можете обратиться за вдохновением, если хотите создать свой собственный.   -  person AndrewC    schedule 31.08.2014
comment
@AndrewC да, я просмотрел эту главу RWH, но обнаружил, что она бесполезна для моего случая. Я хочу, чтобы цепочка парсеров была создана из первой строки файла, которая содержит заголовки столбцов, и пример в моем вопросе упрощен, чтобы прояснить проблему, которая у меня была. Кроме того, мне нравится идея, которая пришла мне в голову, и я хочу сначала попробовать заставить ее работать, прежде чем использовать другие библиотеки.   -  person Alexander Kusev    schedule 31.08.2014
comment
Гранд. В любом случае, приятно знать, что вы решили свою проблему. Не могли бы вы вставить свой ответ в поле для ответа, а не в вопрос, пожалуйста? Спасибо.   -  person AndrewC    schedule 31.08.2014


Ответы (1)


Проблема заключается в неправильном вводе: в моей строке заголовка обязательно будет \n или \r\n, которые будут перехвачены endOfLine, а в моем примере ввода не было \n.

Рабочая версия

test = parseOnly (doTestParse []) "<FIELD1>\n"
person Alexander Kusev    schedule 31.08.2014