Reputation: 2001
I'm completing some exercism exercises. One is a Binary tree (although the context is not relevant to the question as I have experienced this previously in Swift)
I would like to put the following function on one line as:
func allData () -> [Int] {
return ( left?.allData() ?? [] ) + [data] + ( right?.allData() ?? [] )
}
But the error is 'Int' is not convertible to '[Int]'
Ok, but splitting into separate lines is fine:
func allData () -> [Int] {
let leftdata = left?.allData() ?? []
let rightdata = right?.allData() ?? []
return ( leftdata ) + [data] + ( rightdata )
}
In fact it will compile with either the left data, right data and [data], but not both.
Within exercism I can see that people did not solve this in one line.
So why is
return ( left?.allData() ?? [] ) + [data] + ( right?.allData() ?? [] )
invalid?
Upvotes: 0
Views: 97
Reputation: 2477
It won't answer your "why" question, but this might offer you an alternative if you want to keep it as a one-liner:
func allData() -> [Int] {
return [left?.allData() ?? [], [data], right?.allData() ?? []].flatMap { $0 }
}
or
func allData() -> [Int] {
// The first flatMap removes nil elements and the second flattens the array
return [left?.allData(), [data], right?.allData()].flatMap { $0 }.flatMap { $0 }
}
Upvotes: 1
Reputation: 42143
I've seen this often with multiple entries added together. The compiler's type processing sometimes gets confused when combining optionals and non optional types (3 or more) in a single statement.
There is a very similar question here:
http://stackoverflow.com/q/43595162/5237560
and another one here:
http://stackoverflow.com/q/42568446/5237560
In short, the compiler needs help in some cases which are not detected as "too complex" but actually result in the wrong data type being inferred.
Upvotes: 3
Reputation: 238
In many cases, xcode does not compile a statement because it is too complex to be compiled n a reasonable time. Therefore, splitting the statement solves the issue.
Upvotes: 0