Steps to reproduce
import Control.Monad.State
import Lightyear
import Lightyear.Char
import Lightyear.Combinators
import Lightyear.Strings
-- hide the one from Lightyear.Strings
%hide Parser
Parser : Type -> Type
Parser = ParserT String (State Integer)
pModify : Parser ()
pModify = do
token "+"
modify (+ 1)
pTextBlock : Parser String
pTextBlock = pack <$> many anyChar
parser : Parser (List String)
parser = manyTill (choice alts) eof
where
alts : List (Parser String)
alts = [ pure "" <* ((pModify <* string "can'thappen") <|> pModify)
, pTextBlock
]
testParse : Parser a -> String -> Either String (a, Integer)
testParse p src =
let initialVal = 0
Id (r,s) = flip runStateT initialVal $ execParserT p (initialState Nothing src 8)
in case r of
MkReply _ (Success x) => Right (x,s)
MkReply _ (Failure es) => Left $ concat $ intersperse "\n" $ map display es
Running
λΠ> :exec testParse parser "+ho ho"
gives
Observed behaviour
The returned value means that our state had been modified two times. And this is because of the alternative:
((pModify <* string "can'thappen") <|> pModify)
which first enters the left branch (which won't succeed due to dummy string parse at the end), and then the right branch kicks in, and succeeds.
Expected behavior
If the default behavior is to backtrack, then the result of the transformer needs to be discarded as well.
Steps to reproduce
Running
gives
Observed behaviour
The returned value means that our state had been modified two times. And this is because of the alternative:
which first enters the left branch (which won't succeed due to dummy string parse at the end), and then the right branch kicks in, and succeeds.
Expected behavior
If the default behavior is to backtrack, then the result of the transformer needs to be discarded as well.