The parsers you build will always try to continue; if necessary, the entry will be discarded or added. However, pFail is a dead end. It acts as a unit element for <|> .
In your parser, however, there is no other alternative if the input does not match the language recognized by the parser. In your specification, you say you want the parser to fail on s2 input. Now he fails with the message that this fails, and you are surprised.
Maybe you do not want it to fail, but you want to stop accepting further data? In this case, replace pFail with return [] .
Please note that the text:
do rest <- myParse pi `opt` [] return $ expr:rest
can be replaced by (expr:) <$> (myParse pi `opt` [])
The natural way to solve your problem is probably something like
pIndented p = do i <- pGetIndent (:) <$> p <* pEOL <*> pMany (pToken (take i (repeat ' ')) *> p <* pEOL) pIndent = length <$> pMany (pSym ' ')
source share