これらのパーサーを直接使用できるかどうかはわかりませんが、一般的には、パーサーと残り物を注入できるストリーミングを組み合わせることで実現できます。
たとえば、attoparsec-conduitを使用すると、パーサーをコンジットに変えることができます。
sinkParser :: (AttoparsecInput a, MonadThrow m)
=> Parser a b -> Consumer a m b
whereConsumer
は特別な種類のコンジットで、出力を生成せず、入力のみを受け取り、最終的な値を返します。
コンジットは残り物をサポートするため、オプションでストリームにプッシュされる値をコンジットに返すパーサーを変換するヘルパー メソッドを作成できます。
import Data.Attoparsec.Types
import Data.Conduit
import Data.Conduit.Attoparsec
import Data.Functor
reinject :: (AttoparsecInput a, MonadThrow m)
=> Parser a (Maybe a, b) -> Consumer a m b
reinject p = do
(lo, r) <- sinkParser p
maybe (return ()) leftover lo
return r
次に、標準パーサーを を使用してコンジットに変換しsinkParser
、これらの特別なパーサーを を使用して変換しreinject
、パーサーの代わりにコンジットを結合します。