Unable to start a line with an Int parser
sbeitzel opened this issue · 1 comments
Given that I want to parse an input line that looks like this: (AoC 2022, number 4)
2-4,6-8
I reckon that what I want to wind up with is four integers: the starting and ending points for Elf A and Elf B.
Let's define ElfPair
as:
struct ElfPair {
let firstA: Int
let firstB: Int
let secondA: Int
let secondB: Int
}
Now, let's try to parse it:
let pairParser = Parse(ElfPair.init) {
Int.parser()
"-"
Int.parser()
","
Int.parser()
"-"
Int.parser()
}
The compiler complains on the first Int.parser()
, saying, "Ambiguous use of buildExpression"
I can make the compiler shut up by adding an initial literal parser for the empty string, but this seems ... icky:
let pairParser = Parse(ElfPair.init) {
""
Int.parser()
"-"
Int.parser()
","
Int.parser()
"-"
Int.parser()
}
You need to supply more type information due to certain limitations of result builders in Swift. This was detailed in this discussion.
To fix you can either do this:
let pairParser = Parse.init(input: Substring.self, ElfPair.init) {
Int.parser()
"-"
Int.parser()
","
Int.parser()
"-"
Int.parser()
}
Or you can define a whole new parser type using the body
-style of parsing, which can be easier for the compiler to process for large, complex parsers:
struct ElfPairParser: Parser {
var body: some Parser<Substring, ElfPair> {
Parse(ElfPair.init) {
Int.parser()
"-"
Int.parser()
","
Int.parser()
"-"
Int.parser()
}
}
}
Also this is not an issue with the library so I am going to convert this to a discussion.