Hi,

when thinking about this SO question, I couldn't find a combinator that allows a parser to optionally fail without consuming input, or consume input and return its value. So I'm suggesting such a function:

-- | @emptyIf p@ parses @p@ and if its return value is @Nothing@, pretends
-- that an error has occured with no input consumed.
--
-- If @p@ fails and consumes some input, so does @emptyIf p@. Combine with
-- 'try' if this is undesirable.

emptyIf :: (Stream s m t) => ParsecT s u m (Maybe a) -> ParsecT s u m a
emptyIf p = ParsecT $ \s cok  cerr eok eerr ->
                        let cok' (Just x) s e = cok x s e
                            cok' Nothing  _ e = eerr e
                            eok' (Just x) s e = eok x s e
                            eok' Nothing  _ e = eerr e
                        in unParser p s cok' cerr eok' eerr

With this function, the answer to the SO question becomes really easy:

rcomb :: (Stream s m t) => ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
rcomb p q = emptyIf $ runMaybeT (opt p *> opt q)
  where
    opt = MaybeT . optional -- optional from Control.Applicative!

Whenever p or q fails without consuming input, then rcomb p q fails without consuming input.

Unfortunately ParsecT constructor isn‘t exported so I’m not able to implement it outside parsec. (Perhaps it would make sense to export ParsecT in some module such as Text.Parsec.Internal?) Therefore I'm suggesting to add such a function to parsec (darcs patch included). Perhaps change the name, I couldn't think of anything better.

Best regards,
Petr