Apache-2.0 licensed by Chris Martin
Maintained by Chris Martin, Julie Moronuki
This version can be pinned in stack with:attoparsec-run-,1870

Module documentation for

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 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 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


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 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.

Changes (2023-04-10)

New in Data.Attoparsec.Run:

inputState :: (Monoid i, MonadState [i] m) => RestorableInput m i

New in Data.Attoparsec.ByteString.run:

parseOnlyStrict :: ByteString -> Parser a -> Either ParseError a
parseOnlyLazy :: Lazy.ByteString -> Parser a -> Either ParseError a

New in Data.Attoparsec.Text.run:

parseOnlyStrict :: Text -> Parser a -> Either ParseError a
parseOnlyLazy :: Lazy.Text -> Parser a -> Either ParseError a (2023-01-09)

New function:

newRestorableIO :: IO i -> IO (RestorableInput IO i)

This makes it easy to turn any IO input source into a RestorableInput, backed by an IORef that holds any unparsed remainder. (2023-01-09)

Initial release