To understand the behavior of megaparsec's <|> operator it is useful to know about "consuming" and "non-consuming" (or "empty") parses. To illustrate that concept I'll compare a literal string parser to a parser that parses each character separately, watch:
> let p = string "abc"
> let q = sequence [char 'a', char 'b', char 'c']
> parseMaybe (p <|> string "abd") "abd")
Just "abd"
> parseMaybe (q <|> string "abd") "abd"
Nothing
So, what happened? Well, when string "abc" tries to parse the string "abd" it fails without consuming any input. Or you can think of it as backtracking back to the beginning of the string. In contrast, the parser sequence [char 'a', char 'b', char 'c'] does consume the 'a' and 'b' characters even if it fails. In this case, <|> will not even try to use the string "abd" parser.
You can manually force the parser to backtrack by using the try function as follows:
> parseMaybe (try q <|> string "abd") "abd"
Just "abd"
But note that this can cause exponential running time, so try to avoid it.
To answer your question given this information: the error information will be combined but only if both arguments of <|> are failing without consuming any input. If either consumes input, then only the error information from that branch is used.
I'm Glyn Normington. I dipped into Haskell briefly in about 2011, but recently got a little deeper into it when I taught a second year functional programming module at Winchester University, UK. I'm a retired programmer with 39 years experience and try to pass on some general tips in the module. I came here after recently deleting my Reddit account. (I've been on the Fediverse for a while as fosstodon.org/@underlap.)
I know this is not directly related to Haskell and it uses a lot of category theory. But I think at least the introduction is relatively readable and already has some interesting observations, such as the criterions to compare notations:
A notation is better if it absorbes more equations, by which we mean that instead of using an explicit equation to identify two terms they become syntactically equal in the improved notation.
A superior notation absorbs more invariants, so that malformed terms cannot be written as such.
And their ultimate goal:
The ultimate aim of this tutorial is to persuade the reader to accept a new and multifaceted vision of syntax which we (rather grandly) call syntactic trinitarianism: terms, diagrams, graphs.
I would love a visualization tool for Haskell that converts terms into diagrams.
I suspect that comment predates the existence of capi and is trying to avoid having some other actual calling convention like stdcall because the function pointer is actually invoked from some C code in the RTS. capi is a sort of pseudo-calling-convention in that it generates some C code and then calls that stub.
Have you tried using a capi defined funptr there to see what happens?
Thank you, that's indeed a reasonable suspicion. I haven't tried because this is for a PR that's been submitted to me and I actually have no idea how this could blow up in my face later (or even worse, not blow up an silently corrupt stuff)
Haskell
Newest