Skip to content

optional doesn't propagate fail when used with <|> #235

Closed
@Hi-Angel

Description

@Hi-Angel

Describe the bug

So, I'm not clear why, but when you execute under optionMaybe a code that uses two optionals, 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. Down here are even simpler steps-to-reproduce

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 "")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions