понимание attoparsec - PullRequest
       13

понимание attoparsec

5 голосов
/ 27 августа 2010

attoparsec был предложен мне для анализа файла, теперь я должен понять, как его использовать;кто-то дал мне этот кусок кода:

#

type Environment = M.Map String String 
import Data.Attoparsec (maybeResult)
import qualified Data.Attoparsec.Char8 as A
import qualified Data.ByteString.Char8 as B
environment :: A.Parser Environment
environment = M.fromList <$> A.sepBy entry A.endOfLine
parseEnvironment = maybeResult .flip A.feed B.empty . A.parse environment
spaces = A.many $ A.char ' '
entry = (,) <$> upTo ':' <*> upTo ';'
upTo delimiter = B.unpack <$> A.takeWhile (A.notInClass $ delimiter : " ")
                      <* (spaces >> A.char delimiter >> spaces)

, который работает очень хорошо, но я не знаю почему: в чем причина использования flip, не проще лиАргумент А. кормить в другом порядке?и почему там B.empty?есть ли учебник о том, что я могу изучать?заранее спасибо

1 Ответ

4 голосов
/ 27 августа 2010

Существует объяснение необходимости feed в ответах на этого вопроса StackOverflow .Как говорит Брайан О'Салливан (создатель Attoparsec):

Если вы пишете синтаксический анализатор attoparsec, который потребляет столько входных данных, сколько возможно до сбоя, вы должны указать частичное продолжение результата, когда выдостиг конца вашего ввода.

Вы можете сделать это, введя пустую строку.

Я признаю, что написал соответствующий код, и на самом деле я не сделал 'В этом случае используйте pointfree.Простая композиция для меня здесь имеет смысл: вы запускаете парсер (A.parse environment), вы говорите, что все готово (flip A.feed B.empty), и вы конвертируете в Maybe как базовую обработку ошибок (* 1016)*).На мой взгляд, это выглядит чище, чем указанная версия:

parseEnvironment b = maybeResult $ A.feed (A.parse environment b) B.empty

Остальное, я думаю, довольно идиоматический аппликативный разбор , хотя я не уверен, почему я бы использовал >>вместо *>.

...