Consider the string "(=x250) toto e"
, and the function:
charToText :: Char -> Text
charToText c = pack [c]
The string is successfully parsed by:
mconcat <$> manyTill (charToText <$> anyChar) (char 'e')
with the expected result "(=x250) toto "
.
However, the parser:
mconcat <$> manyTill (charToText <$> anyChar) endOfInput
returns Partial _
.
Why is it so ? I thought endOfInput
would succeed at the end of the string and stop manyTill
(as in the first example).
To get a complete answer, you'll need to provide a fully self-contained example that generates the Result: incomplete input
error message, but your Attoparsec parser is working correctly. You can see similar behavior with a much simpler example:
λ> parse (char 'e') "e"
Done "" 'e'
λ> parse endOfInput ""
Partial _
Attoparsec parsers by design allow incremental supply of additional input. When they are run on some (potentially partial) input, they return a Done
result if the parser unconditionally succeeds on the supplied input. They return a Partial
result if more input is needed to decide if the parser succeeds.
For my example above, char 'e'
always successfully parses the partial input "e"
, no matter what additional input you might decide to supply, hence the result is a Done
.
However, endOfInput
might succeed on the partial input ""
, but only if no additional input is going to be supplied. If there is additional input, endOfInput
will fail. Because of this, a Partial
result is returned.
It's the same for your example. The success of your second parser depends on whether or not additional input is supplied. If there's no additional input, the parser is Done
, but if there is additional input, the parser has more to do.
You will either need to arrange to run your parser with parseOnly
:
λ> parseOnly (manyTill anyChar endOfInput) "foo"
Right "foo"
or you will feed
your parse result an empty bytestring which will indicate that no further input is available:
λ> parse (manyTill anyChar endOfInput) "foo"
Partial _
λ> feed (parse (manyTill anyChar endOfInput) "foo") ""
Done "" "foo"