È possibile utilizzare StateT s Parser
, è sufficiente ricordare che il backtracking nel parser ripristina anche lo stato, in modo da ottenere solo le azioni stateful che sono state invocate sul percorso del codice con l'analisi corretta.
{-# 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)
Inoltre, siamo in grado di utilizzare la maggior parte delle Attoparsec
combinatori, fuori dalla scatola, perché hanno i tipi generici con Alternative
, MonadPlus
, Applicative
o Monad
vincoli, e StateT
definisce le istanze di sollevamento-through per questi. Possiamo usare lift
per il numero di base Parser
-s.
fonte
2015-05-28 13:56:40
Grazie, molto apprezzato. Sembra che questo mi porterà lì usando Attoparsec, quindi lo contrassegnerò come risposta. –