do {
let range = 0...512
_ = range.publisher
.map {
($0, $0 + $0)
}
.reduce ((0, 0)) {
($0.0 + $1.0, $0.1 + $1.1)
}
}
But, the next one doesn't and produces the error The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
do {
_ = (0...512).publisher // The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
.map {
($0, $0 + $0)
}
.reduce ((0, 0)) {
($0.0 + $1.0, $0.1 + $1.1)
}
}
I don't understand why, but It appears that the presence of the reduce operator is upsetting the compiler because the following code sans the reduce operator compiles.
This often happens with complex expressions like this because there are very few constraints around what the actual types are so the compiler struggles to figure out the correct overloads. (Are those integer literals Ints or UInt16s or Doubles?). Breaking out the range into its own statement allows the type checker to solve two simpler problems since it can fairly easily compute the type of range. Similarly, removing the reduce call simplifies the overall expression enough to allow it to be resolved in time, although you may see that the containing function takes a long time to type-check.
If you assign the result of this expression to a variable and give it an explicit type, the type checker will have more information going in and should be able to resolve all the types in time.
Yeah, there is an unfortunate interaction between literals and highly-overloaded operators that causes the type-checking search space to explode in some circumstances. Ensuring the literals have their types as early/separately as possible is a decent workaround.
ETA: just to explicitly address the question, the reduce call specifically makes things so dramatically worse likely because it introduces two new integer literals and several new + operators, all without providing any additional type context.