I am converting some functioning Haskell code that uses Parsec to instead use Attoparsec in the hope of getting better performance. I have made the changes and everything c
I've run into this problem before and my understanding is that it's caused by the way that <|>
works in the definition of sepBy
:
sepBy1 :: Alternative f => f a -> f s -> f [a]
sepBy1 p s = scan
where scan = liftA2 (:) p ((s *> scan) <|> pure [])
This will only move to pure []
once (s *> scan)
has failed, which won't happen just because you're at the end of the input.
My solution has been just to call feed
with an empty
ByteString on the Result
returned by parse
. This might be kind of a hack, but it also seems to be how attoparsec-iteratee deals with the issue:
f k (EOF Nothing) = finalChunk $ feed (k S.empty) S.empty
As far as I can tell this is the only reason that attoparsec-iteratee
works here and plain old parse
doesn't.