Is there some "easy" way (e.g. something I am missing in Attoparsec or some other library) to convert a defined Attoparsec parser that parses from ByteString to the one that parses from Text?
For example I have:
import Data.Attoparsec.ByteString.Char8
myTypeByteStringParser :: Parser MyType
What's the way to transform it into:
import Data.Attoparsec.Text
myTypeTextParser :: Parser MyType
It does look like contramap (from hoogling type signature) but it is probably not possible to define Contravariant for Parser?
This is possible in general and you don't need to fork
attoparsec. Inconsideratelyattoparsecdoesn't expose enough of its internals, but don't let that stop us:{,un}buffer{BS,Text}are adapted from the respective internal modulesData.Attoparsec.{ByteString,Text}.Buffer.Was a good excuse for me to update
true-nameto work with more recent GHC though. Depending on how up-to-date you are, you may need the WIP from GitHub.It's probably not terrible for performance, as long as you keep in mind that each time you use
textToBSParser, the entire input gets fed throughencodeUtf8with any leftover converted back viadecodeUtf8, and vice versa forbsToTextParser. If you only convert aParseronce at the top-level, it shouldn't be too different from simply converting the input as the other answer suggests.PS: I haven't tested this beyond
PPS: for your own parsers, you might be able to leverage
OverloadedStringsand writep :: IsString s => AIT.Parser s ainstead, with{-# SPECIALISE p :: AT.Parser a #-}pragmas. I've not explored how workable this idea is.