2015-05-28 27 views
6

Sto utilizzando Attoparsec e vorrei tenere traccia di un valore di stato utente durante un'attività di analisi.Attoparsec supporta il salvataggio e la modifica dello stato dell'utente?

Ho familiarità con le funzioni monadiche getState, putState e modifyState di Parsec, ma non riesco a trovare un analogo all'interno di Attoparsec. C'è un modo banale per farlo con qualcosa di interno ad Attoparsec o usando una monade di stato?

risposta

5

È 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.

+0

Grazie, molto apprezzato. Sembra che questo mi porterà lì usando Attoparsec, quindi lo contrassegnerò come risposta. –

Problemi correlati