Description
Describe the bug
So, I'm not clear why, but when you execute under Down here are even simpler steps-to-reproduceoptionMaybe
a code that uses two optional
s, then even if the code consumes input before failing, optionMaybe
thinks it didn't. The interesting feature of this bug is that if you remove at least one optional
, it will fail as expected.
Spent a few hours digging, first to a parsing bug and then to the Parsing bug (pun intended), came down with the minimal steps below 😊
To Reproduce
UPD: simpler steps-to-reproduce are in this comment
Run the following code:
module Main where
import Prelude
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Effect.Console (logShow)
import Parsing (Parser, fail, runParser)
import Parsing.Combinators (optionMaybe, optional)
import Parsing.String (char)
import Parsing.String.Basic (whiteSpace)
type TextParser = Parser String
-- Parsing trailing whitespace provides a number of benefits compared to parsing
-- leading whitespace. For details see chapter 3 of "Design Patterns for Parser
-- Combinators (Functional Pearl)" paper.
lexeme :: ∀ a. TextParser a -> TextParser a
lexeme p = p <* optional whiteSpace
parseTypes :: TextParser String
parseTypes = do
_ <- lexeme $ lexeme $ (char 'f' *> char 'o' *> char 'o')
fail "test failure"
parseImpl :: TextParser String
parseImpl = do
optionMaybe parseTypes >>= case _ of
Nothing -> pure ""
Just x -> pure x
main :: Effect Unit
main = logShow $ runParser "foo" parseImpl
Expected behavior
Code should return (Left "test failure")
because the paragraph being executed under optionMaybe
has consumed the input (thrice even) before failing.
Actual behavior
It returns (Right "")