-
Notifications
You must be signed in to change notification settings - Fork 43
Open
Description
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 esRunning
λΠ> :exec testParse parser "+ho ho"
gives
Right (["", "ho ho"], 2)
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.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels