I'd like to understand what could be the least painful way for programmer and compiler to get the following code to compile in a reasonable time
extension Array {
func unflat() -> [[Element]] {
return self.map{[$0]}
}
}
let EnglishLayout: [[String]] = [
["1", "!"],
["2", "@"],
["3", "#"],
["4", "$"],
["5", "%"],
["6", "^"],
["7", "&"],
["8", "*"],
["9", "(", "-", "_"],
["0", ")", "=", "+"],
["Q", "`", "~"]
] + ["W", "E", "R", "T", "Y", "U", "I"].unflat() + [
["O", "[", "{"],
["P", "]", "}"],
] + ["A", "S", "D", "F", "G", "H", "J"].unflat() + [
["K", ";", ":"],
["L", "'", "\""],
["\\", "|"],
] + ["Z", "X", "C", "V", "B", "N", "M"].unflat() + [
[",", "<"],
[".", ">"],
["/", "?"],
]
It simply fails to compile for me with 'too complex type expression'
I added the analyze flag to build settings and commented out the last two parts
-Xfrontend -warn-long-expression-type-checking=100
Apparently the Swift compiler is too intelligent to choose the path of the least resistance and simply concatenate the arrays as instructed by the programmer with an explicit type declaration. Coming from Dart and TypeScript it's not at all obvious to me how to tackle issues like this.
Unfortunately, I can't provide any explanation on why the compiler isn't able to evaluate this fairly simple array. However, the swift compiler is often overwhelmed by any big / slightly complex array expressions. I see, therefore, three possible solutions for your case:
... + ["A", "B"].unflat()
but [["A"], ["B"]]
let EnglishLayout: [[String]] = {
var layout: [[String]] = [
["1", "!"],
["2", "@"],
["3", "#"],
["4", "$"],
["5", "%"],
["6", "^"],
["7", "&"],
["8", "*"],
["9", "(", "-", "_"],
["0", ")", "=", "+"],
["Q", "`", "~"]
]
layout += ["W", "E", "R", "T", "Y", "U", "I"].unflat()
layout += [
["O", "[", "{"],
["P", "]", "}"]
]
layout += ["A", "S", "D", "F", "G", "H", "J"].unflat()
layout += [
["K", ";", ":"],
["L", "'", "\""],
["\\", "|"]
]
layout += ["Z", "X", "C", "V", "B", "N", "M"].unflat()
layout += [
[",", "<"],
[".", ">"],
["/", "?"]
]
return layout
}()