Does Attoparsec support saving and modifying user state?
Asked Answered
N

1

6

I'm using Attoparsec, and I would like to track a user state value throughout a parsing task.

I'm familiar with the monadic functions getState, putState, and modifyState of Parsec, but I can't seem to find an analogue within Attoparsec. Is there a trivial way to do this with something internal to Attoparsec or by using a State monad?

Non answered 28/5, 2015 at 11:27 Comment(0)
C
5

You can use StateT s Parser, just be mindful that backtracking in the parser also rolls back the state, so you only get those stateful actions that were invoked on the code path with the successful parse.

{-# LANGUAGE OverloadedStrings #-}

import Data.Attoparsec.ByteString.Char8
import Control.Monad.State
import Control.Applicative

test :: StateT Int Parser ()
test = do
  many $ choice [
    (modify (+1) *> lift (string "car")),
    (modify (+1) *> lift (string "cat"))]
  pure ()

parseOnly (runStateT test 0) "catcatcat"
-- Right ((),3)

Also, we can use most of the Attoparsec combinators out of the box, because they have generic types with Alternative, MonadPlus, Applicative or Monad constraints, and StateT defines lift-through instances for these. We can use lift for the basic Parser-s.

Cubical answered 28/5, 2015 at 13:56 Comment(1)
Thanks, much appreciated. It appears this will get me there using Attoparsec, so I'll mark it as the answer.Non

© 2022 - 2024 — McMap. All rights reserved.