stevenpcurtis
stevenpcurtis

Reputation: 2001

Swift return result of function calls

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

Answers (3)

Matusalem Marques
Matusalem Marques

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

Alain T.
Alain T.

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

Tarek A.
Tarek A.

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

Related Questions