This package fixes a number of problems with the API that Attoparsec provides
for running parsers.
The difficulties stem from the that that Attoparsec’s IResult
type encompasses
three situations: When parsing has succeeded, when parsing has failed, and when
parsing is awaiting further input. This is insufficient to describe situations
in which we know we are dealing with a subset of these three cases. We address
this by introducing two smaller types: FinalResult
and ParseError
.
FinalResult
FinalResult
represents a result that we know not to be partial; for example,
the sort of result that we get when running a parser using parseWith
.
data FinalResult i a = FinalResult i (Either ParseError a)
ParseError
ParseError
represents only the case in which parsing has failed.
data ParseError = ParseError [String] String
Our showParseError
function gives an error string in the same format as
Attoparsec’s eitherResult
function.
showParseError :: ParseError -> String
BufferedInput
The BufferedInput
type corresponds to two arguments of Attoparsec’s
parseWith
, the initial input and the action to obtain more input.
data BufferedInput m i = BufferedInput i (m i)
In each of the modules Data.Attoparsec.ByteString.Run
and
Data.Attoparsec.Text.Run
, we provide a function called parseStream
. This
closely corresponds to Attoparsec’s parseWith
function, but ours returns the
more specific FinalResult
type, rather than Result
, reflecting the fact that
a result returned here is never partial.
parseStream :: Monad m =>
BufferedInput m ByteString -> Parser a -> m (FinalResult ByteString a)
RestorableInput
RestorableInput
offers a new way to do streaming parsing that may be more
convenient than parseStream
and BufferedInput
. This type represents an input
stream with the ability to push unused input back to it.
data RestorableInput m i = RestorableInput (m i) (i -> m ())
We use this type with the parseAndRestore
function:
parseAndRestore :: Monad m =>
RestorableInput m ByteString -> Parser a -> m (Either ParseError a)
This shifts the burden of storing the unused remainder to feed back into the
next parsing step from the user of parseStream
to the definer of the
RestorableInput
.