
Am Dienstag 05 Mai 2009 17:38:35 schrieb mwinter@brocku.ca:
Thanks, but I want a nice solution not another, even more complicated, workaround.
I'm afraid you're out of luck there. Parsec carries a ParseError around even for successful parses (where it's a SourcePos and and empty list of messages). When binding two parsers, if the second doesn't consume any input, for the overall result it calls mergeErrorReply, which calls mergeError from Text.ParserCombinators.Parsec.Error: mergeError :: ParseError -> ParseError -> ParseError mergeError (ParseError pos msgs1) (ParseError _ msgs2) = ParseError pos (msgs1 ++ msgs2) So that doesn't look at the position of the second error :( You could change the sources of parsec, the least intrusive would probably be to modify mergeError: mergeError :: ParseError -> ParseError -> ParseError mergeError (ParseError _ []) pe2 = pe2 mergeError (ParseError pos msgs1) (ParseError _ msgs2) = ParseError pos (msgs1 ++ msgs2) or you could employ an ugly workaround like setPosAndFail :: tok -> SourcePos -> String -> GenParser tok st a setPosAndFail dummy pos msg = do setPosition pos inp <- getInput setInput (dummy:inp) tokenPrim (const "") (\p _ _ -> p) Just fail msg myFail :: SourcePos -> String -> GenParser Char st a myFail = setPosAndFail 'a' to pretend you actually consumed some input. It works: *TestWorkAround> test Left (line 100, column 100): Test but isn't pretty.