I've defined the following custom parser:
newtype St = St Int
type TxsParser = ParsecT String St (State St)
Now to be able to run this parser, I have to use the runParserT
function.
runParserT :: Stream s m t
=> ParsecT s u m a
-> u
-> SourceName
-> s
-> m (Either ParseError a)
Which instantiated to my custom parser reads:
runParserT :: ParsecT String St (State St) a
-> St
-> SourceName
-> String
-> State St (Either ParseError a)
But this means that if I want to evaluate the result of runParserT
(which is a state monad) I have to supply another initial state (of type St
in this case). For instance:
evalState (runParserT myParser (St 0) fp input) (St 0)
While this works, it seems wrong that I have to repeat the state twice. Does this mean that mixing ParsecT
and the State
monads is not a good idea?
ParsecT provides state. State provides state. Using both together gives you two independent states.
You have to initialize both, which is why you see it twice.
There's nothing wrong with using them together if you want two separate sources of state (e.g. one that backtracks and one that doesn't), but if you only wanted one, this is clearly not what you'd do.